Fixed JSArray for 1.5 semantics stuff. Changed readEvalFile to stop

doing line at a time nonsense. Fixed ExprNode::Index cases to use
InvokeExprNode instead of Binary.


git-svn-id: svn://10.0.0.236/trunk@82119 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rogerl%netscape.com
2000-11-01 01:39:43 +00:00
parent c389e67de6
commit 36884f6d49
8 changed files with 246 additions and 126 deletions

View File

@@ -1219,9 +1219,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (i->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(i->op);
TypedRegister base = genExpr(b->op1);
ret = call(getElement(base, genExpr(b->op2)), base, args);
InvokeExprNode *ii = static_cast<InvokeExprNode *>(i->op);
TypedRegister base = genExpr(ii->op);
ret = call(getElement(base, genExpr(ii->pairs->value)), base, args); // FIXME, only taking first index
}
else
ASSERT("WAH!");
@@ -1229,13 +1229,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
break;
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister base = genExpr(b->op1);
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
TypedRegister base = genExpr(i->op);
JSClass *clazz = dynamic_cast<JSClass*>(base.second);
if (clazz) {
// look for operator [] and invoke it
}
TypedRegister index = genExpr(b->op2);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
ret = getElement(base, index);
}
break;
@@ -1275,9 +1275,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
ret = getElement(base, index);
ret = binaryOp(xcrementOp, ret, loadImmediate(1.0));
setElement(base, index, ret);
@@ -1300,9 +1300,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
ret = elementXcr(base, index, xcrementOp);
}
else
@@ -1351,9 +1351,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
setElement(base, index, ret);
}
else
@@ -1384,9 +1384,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
TypedRegister v = getElement(base, index);
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), v, ret);
setElement(base, index, ret);
@@ -1442,7 +1442,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r1, r2);
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r2, r1);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
branchFalse(falseBranch, ret);

View File

@@ -176,8 +176,10 @@ ICodeModule* Context::compileFunction(const String &source)
JSValue Context::readEvalFile(FILE* in, const String& fileName)
{
String buffer;
string line;
LineReader inReader(in);
int ch;
while ((ch = getc(in)) != EOF)
buffer += static_cast<char>(ch);
JSValues emptyArgs;
JSValue result;
@@ -187,45 +189,34 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName)
autosaver<Linkage*> linkage(mLinkage, 0);
autosaver<InstructionIterator> pc(mPC);
while (inReader.readLine(line) != 0) {
appendChars(buffer, line.data(), line.size());
try {
Arena a;
Parser p(getWorld(), a, buffer, fileName);
StmtNode *parsedStatements = p.parseProgram();
ASSERT(p.lexer.peek(true).hasKind(Token::end));
try {
Arena a;
Parser p(getWorld(), a, buffer, fileName);
StmtNode *parsedStatements = p.parseProgram();
/*******/
ASSERT(p.lexer.peek(true).hasKind(Token::end));
{
PrettyPrinter f(stdOut, 30);
{
PrettyPrinter f(stdOut, 30);
{
PrettyPrinter::Block b(f, 2);
f << "Program =";
f.linearBreak(1);
StmtNode::printStatements(f, parsedStatements);
}
f.end();
PrettyPrinter::Block b(f, 2);
f << "Program =";
f.linearBreak(1);
StmtNode::printStatements(f, parsedStatements);
}
stdOut << '\n';
f.end();
}
stdOut << '\n';
/*******/
// Generate code for parsedStatements, which is a linked
// list of zero or more statements
ICodeModule* icm = genCode(parsedStatements, fileName);
if (icm) {
result = interpret(icm, emptyArgs);
delete icm;
}
clear(buffer);
} catch (Exception &e) {
/* If we got a syntax error on the end of input,
* then wait for a continuation
* of input rather than printing the error message. */
if (!(e.hasKind(Exception::syntaxError) &&
e.lineNum && e.pos == buffer.size() &&
e.sourceFile == fileName)) {
stdOut << '\n' << e.fullMessage();
clear(buffer);
}
// list of zero or more statements
ICodeModule* icm = genCode(parsedStatements, fileName);
if (icm) {
result = interpret(icm, emptyArgs);
delete icm;
}
} catch (Exception &e) {
throw new JSException(e.fullMessage());
}
return result;
}
@@ -566,7 +557,7 @@ void Context::initContext()
// the 'Math' object just has some useful properties
JSMath::initMathObject(mGlobal);
JSArray::initArrayObject(mGlobal);
// This initializes the state of the binary operator overload mechanism.
// One could argue that it is unneccessary to do this until the 'Operators'
@@ -1037,6 +1028,7 @@ using JSString throughout.
JSArray* array = value.array;
(*registers)[dst(ge).first] = (*array)[(*registers)[src2(ge).first]];
}
// FIXME - else case does what/? GET_PROPERTY of toString(index) ?
}
break;
case SET_ELEMENT:
@@ -1047,6 +1039,7 @@ using JSString throughout.
JSArray* array = value.array;
(*array)[(*registers)[src1(se).first]] = (*registers)[src2(se).first];
}
// FIXME - else case does what/? SET_PROPERTY of toString(index) ?
}
break;

View File

@@ -92,9 +92,6 @@ void JSObject::initObjectObject(JSScope *)
{
// The ObjectPrototypeObject has already been constructed by static initialization.
// JSNativeFunction *objCon = new JSNativeFunction(objectConstructor);
// objCon->setProperty(widenCString("prototype"), JSValue(ObjectPrototypeObject));
// g->setProperty(*ObjectString, JSValue(objCon));
}
@@ -251,6 +248,67 @@ static JSValue date_invokor(Context *, const JSValues&)
return JSValue(new JSString("now"));
}
/********** Array Object Stuff **************************/
JSString* JSArray::ArrayString = new JSString("Array");
JSObject *JSArray::ArrayPrototypeObject = NULL;
static JSValue array_constructor(Context *, const JSValues& argv)
{
// argv[0] will be NULL
int argCount = argv.size();
if (argCount > 1)
if (argCount > 2) { // then it's a bunch of elements
JSArray *result = new JSArray(argCount - 1);
for (uint32 i = 1; i < argCount; i++) {
(*result)[i - 1] = argv[i];
}
return JSValue(result);
}
else
return JSValue(new JSArray(JSValue::valueToInteger(argv[1]).i32));
else
return JSValue(new JSArray());
}
static JSValue array_toString(Context *, const JSValues& argv)
{
if (argv.size() > 0) {
JSValue theThis = argv[0];
if (theThis.isArray()) {
StringFormatter f;
f << theThis;
return JSValue(new JSString(f));
}
else
throw new JSException("TypeError : Array::toString called on non array object");
}
return kUndefinedValue;
}
struct ArrayFunctionEntry {
char *name;
JSNativeFunction::JSCode fn;
} ArrayFunctions[] = {
{ "constructor", array_constructor },
{ "toString", array_toString }
// splice, join etc etc
};
void JSArray::initArrayObject(JSScope *g)
{
ArrayPrototypeObject = new JSObject();
ArrayPrototypeObject->setClass(new JSString(ArrayString));
for (uint i = 0; i < sizeof(ArrayFunctions) / sizeof(ArrayFunctionEntry); i++)
ArrayPrototypeObject->setProperty(widenCString(ArrayFunctions[i].name), JSValue(new JSNativeFunction(ArrayFunctions[i].fn) ) );
ASSERT(g->getProperty(*ArrayString).isObject());
JSObject *arrayVariable = g->getProperty(*ArrayString).object;
arrayVariable->setProperty(widenCString("prototype"), JSValue(ArrayPrototypeObject)); // should be DontEnum, DontDelete, ReadOnly
}
/**************************************************************************************/
@@ -260,7 +318,7 @@ JSType Number_Type = JSType(widenCString("Number"), &Integer_Type);
JSType Character_Type = JSType(widenCString("Character"), &Any_Type);
JSType String_Type = JSType(widenCString("String"), &Character_Type);
JSType Function_Type = JSType(widenCString("Function"), &Any_Type, new JSNativeFunction(function_constructor), new JSNativeFunction(function_constructor));
JSType Array_Type = JSType(widenCString("Array"), &Any_Type);
JSType Array_Type = JSType(widenCString("Array"), &Any_Type, new JSNativeFunction(array_constructor), new JSNativeFunction(array_constructor));
JSType Type_Type = JSType(widenCString("Type"), &Any_Type);
JSType Boolean_Type = JSType(widenCString("Boolean"), &Any_Type, new JSNativeFunction(boolean_constructor), new JSNativeFunction(boolean_constructor));
JSType Null_Type = JSType(widenCString("Null"), &Any_Type);

View File

@@ -133,6 +133,7 @@ namespace JSTypes {
JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); }
bool isFunction() const { return (tag == function_tag); }
bool isArray() const { return (tag == array_tag); }
bool isObject() const { return ((tag == object_tag) || (tag == function_tag) || (tag == array_tag) || (tag == type_tag)); }
bool isString() const { return (tag == string_tag); }
bool isBoolean() const { return (tag == boolean_tag); }
@@ -381,12 +382,18 @@ namespace JSTypes {
* Private representation of a JavaScript array.
*/
class JSArray : public JSObject {
static JSObject* ArrayPrototypeObject;
static JSString* ArrayString;
JSValues elements;
uint32 top;
public:
JSArray() : elements(1) { top = 0; }
JSArray(uint32 size) : elements(size) { top = size; }
JSArray(const JSValues &v) : elements(v) {}
static void initArrayObject(JSScope *g);
JSArray() : JSObject(ArrayPrototypeObject), elements(1) { setClass(ArrayString); top = 0; }
JSArray(uint32 size) : JSObject(ArrayPrototypeObject), elements(size) { setClass(ArrayString); top = size; }
JSArray(const JSValues &v) : JSObject(ArrayPrototypeObject), elements(v) { setClass(ArrayString); }
uint32 length()
{
@@ -466,6 +473,7 @@ namespace JSTypes {
class JSException : public gc_base {
public:
JSException(String &mess) : value(JSValue(new JSString(mess))) { }
JSException(char *mess) : value(JSValue(new JSString(mess))) { }
JSException(JSValue v) : value(v) { }
JSValue value;
@@ -669,6 +677,7 @@ namespace JSTypes {
bool getValue() { return mValue; }
};
} /* namespace JSTypes */
} /* namespace JavaScript */

View File

@@ -1219,9 +1219,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (i->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(i->op);
TypedRegister base = genExpr(b->op1);
ret = call(getElement(base, genExpr(b->op2)), base, args);
InvokeExprNode *ii = static_cast<InvokeExprNode *>(i->op);
TypedRegister base = genExpr(ii->op);
ret = call(getElement(base, genExpr(ii->pairs->value)), base, args); // FIXME, only taking first index
}
else
ASSERT("WAH!");
@@ -1229,13 +1229,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
break;
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister base = genExpr(b->op1);
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
TypedRegister base = genExpr(i->op);
JSClass *clazz = dynamic_cast<JSClass*>(base.second);
if (clazz) {
// look for operator [] and invoke it
}
TypedRegister index = genExpr(b->op2);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
ret = getElement(base, index);
}
break;
@@ -1275,9 +1275,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
ret = getElement(base, index);
ret = binaryOp(xcrementOp, ret, loadImmediate(1.0));
setElement(base, index, ret);
@@ -1300,9 +1300,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(u->op);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
ret = elementXcr(base, index, xcrementOp);
}
else
@@ -1351,9 +1351,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
setElement(base, index, ret);
}
else
@@ -1384,9 +1384,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
InvokeExprNode *i = static_cast<InvokeExprNode *>(b->op1);
TypedRegister base = genExpr(i->op);
TypedRegister index = genExpr(i->pairs->value); // FIXME, only taking first index
TypedRegister v = getElement(base, index);
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), v, ret);
setElement(base, index, ret);
@@ -1442,7 +1442,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r1, r2);
ret = binaryOp(mapExprNodeToICodeOp(p->getKind()), r2, r1);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
branchFalse(falseBranch, ret);

View File

@@ -176,8 +176,10 @@ ICodeModule* Context::compileFunction(const String &source)
JSValue Context::readEvalFile(FILE* in, const String& fileName)
{
String buffer;
string line;
LineReader inReader(in);
int ch;
while ((ch = getc(in)) != EOF)
buffer += static_cast<char>(ch);
JSValues emptyArgs;
JSValue result;
@@ -187,45 +189,34 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName)
autosaver<Linkage*> linkage(mLinkage, 0);
autosaver<InstructionIterator> pc(mPC);
while (inReader.readLine(line) != 0) {
appendChars(buffer, line.data(), line.size());
try {
Arena a;
Parser p(getWorld(), a, buffer, fileName);
StmtNode *parsedStatements = p.parseProgram();
ASSERT(p.lexer.peek(true).hasKind(Token::end));
try {
Arena a;
Parser p(getWorld(), a, buffer, fileName);
StmtNode *parsedStatements = p.parseProgram();
/*******/
ASSERT(p.lexer.peek(true).hasKind(Token::end));
{
PrettyPrinter f(stdOut, 30);
{
PrettyPrinter f(stdOut, 30);
{
PrettyPrinter::Block b(f, 2);
f << "Program =";
f.linearBreak(1);
StmtNode::printStatements(f, parsedStatements);
}
f.end();
PrettyPrinter::Block b(f, 2);
f << "Program =";
f.linearBreak(1);
StmtNode::printStatements(f, parsedStatements);
}
stdOut << '\n';
f.end();
}
stdOut << '\n';
/*******/
// Generate code for parsedStatements, which is a linked
// list of zero or more statements
ICodeModule* icm = genCode(parsedStatements, fileName);
if (icm) {
result = interpret(icm, emptyArgs);
delete icm;
}
clear(buffer);
} catch (Exception &e) {
/* If we got a syntax error on the end of input,
* then wait for a continuation
* of input rather than printing the error message. */
if (!(e.hasKind(Exception::syntaxError) &&
e.lineNum && e.pos == buffer.size() &&
e.sourceFile == fileName)) {
stdOut << '\n' << e.fullMessage();
clear(buffer);
}
// list of zero or more statements
ICodeModule* icm = genCode(parsedStatements, fileName);
if (icm) {
result = interpret(icm, emptyArgs);
delete icm;
}
} catch (Exception &e) {
throw new JSException(e.fullMessage());
}
return result;
}
@@ -566,7 +557,7 @@ void Context::initContext()
// the 'Math' object just has some useful properties
JSMath::initMathObject(mGlobal);
JSArray::initArrayObject(mGlobal);
// This initializes the state of the binary operator overload mechanism.
// One could argue that it is unneccessary to do this until the 'Operators'
@@ -1037,6 +1028,7 @@ using JSString throughout.
JSArray* array = value.array;
(*registers)[dst(ge).first] = (*array)[(*registers)[src2(ge).first]];
}
// FIXME - else case does what/? GET_PROPERTY of toString(index) ?
}
break;
case SET_ELEMENT:
@@ -1047,6 +1039,7 @@ using JSString throughout.
JSArray* array = value.array;
(*array)[(*registers)[src1(se).first]] = (*registers)[src2(se).first];
}
// FIXME - else case does what/? SET_PROPERTY of toString(index) ?
}
break;

View File

@@ -92,9 +92,6 @@ void JSObject::initObjectObject(JSScope *)
{
// The ObjectPrototypeObject has already been constructed by static initialization.
// JSNativeFunction *objCon = new JSNativeFunction(objectConstructor);
// objCon->setProperty(widenCString("prototype"), JSValue(ObjectPrototypeObject));
// g->setProperty(*ObjectString, JSValue(objCon));
}
@@ -251,6 +248,67 @@ static JSValue date_invokor(Context *, const JSValues&)
return JSValue(new JSString("now"));
}
/********** Array Object Stuff **************************/
JSString* JSArray::ArrayString = new JSString("Array");
JSObject *JSArray::ArrayPrototypeObject = NULL;
static JSValue array_constructor(Context *, const JSValues& argv)
{
// argv[0] will be NULL
int argCount = argv.size();
if (argCount > 1)
if (argCount > 2) { // then it's a bunch of elements
JSArray *result = new JSArray(argCount - 1);
for (uint32 i = 1; i < argCount; i++) {
(*result)[i - 1] = argv[i];
}
return JSValue(result);
}
else
return JSValue(new JSArray(JSValue::valueToInteger(argv[1]).i32));
else
return JSValue(new JSArray());
}
static JSValue array_toString(Context *, const JSValues& argv)
{
if (argv.size() > 0) {
JSValue theThis = argv[0];
if (theThis.isArray()) {
StringFormatter f;
f << theThis;
return JSValue(new JSString(f));
}
else
throw new JSException("TypeError : Array::toString called on non array object");
}
return kUndefinedValue;
}
struct ArrayFunctionEntry {
char *name;
JSNativeFunction::JSCode fn;
} ArrayFunctions[] = {
{ "constructor", array_constructor },
{ "toString", array_toString }
// splice, join etc etc
};
void JSArray::initArrayObject(JSScope *g)
{
ArrayPrototypeObject = new JSObject();
ArrayPrototypeObject->setClass(new JSString(ArrayString));
for (uint i = 0; i < sizeof(ArrayFunctions) / sizeof(ArrayFunctionEntry); i++)
ArrayPrototypeObject->setProperty(widenCString(ArrayFunctions[i].name), JSValue(new JSNativeFunction(ArrayFunctions[i].fn) ) );
ASSERT(g->getProperty(*ArrayString).isObject());
JSObject *arrayVariable = g->getProperty(*ArrayString).object;
arrayVariable->setProperty(widenCString("prototype"), JSValue(ArrayPrototypeObject)); // should be DontEnum, DontDelete, ReadOnly
}
/**************************************************************************************/
@@ -260,7 +318,7 @@ JSType Number_Type = JSType(widenCString("Number"), &Integer_Type);
JSType Character_Type = JSType(widenCString("Character"), &Any_Type);
JSType String_Type = JSType(widenCString("String"), &Character_Type);
JSType Function_Type = JSType(widenCString("Function"), &Any_Type, new JSNativeFunction(function_constructor), new JSNativeFunction(function_constructor));
JSType Array_Type = JSType(widenCString("Array"), &Any_Type);
JSType Array_Type = JSType(widenCString("Array"), &Any_Type, new JSNativeFunction(array_constructor), new JSNativeFunction(array_constructor));
JSType Type_Type = JSType(widenCString("Type"), &Any_Type);
JSType Boolean_Type = JSType(widenCString("Boolean"), &Any_Type, new JSNativeFunction(boolean_constructor), new JSNativeFunction(boolean_constructor));
JSType Null_Type = JSType(widenCString("Null"), &Any_Type);

View File

@@ -133,6 +133,7 @@ namespace JSTypes {
JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); }
bool isFunction() const { return (tag == function_tag); }
bool isArray() const { return (tag == array_tag); }
bool isObject() const { return ((tag == object_tag) || (tag == function_tag) || (tag == array_tag) || (tag == type_tag)); }
bool isString() const { return (tag == string_tag); }
bool isBoolean() const { return (tag == boolean_tag); }
@@ -381,12 +382,18 @@ namespace JSTypes {
* Private representation of a JavaScript array.
*/
class JSArray : public JSObject {
static JSObject* ArrayPrototypeObject;
static JSString* ArrayString;
JSValues elements;
uint32 top;
public:
JSArray() : elements(1) { top = 0; }
JSArray(uint32 size) : elements(size) { top = size; }
JSArray(const JSValues &v) : elements(v) {}
static void initArrayObject(JSScope *g);
JSArray() : JSObject(ArrayPrototypeObject), elements(1) { setClass(ArrayString); top = 0; }
JSArray(uint32 size) : JSObject(ArrayPrototypeObject), elements(size) { setClass(ArrayString); top = size; }
JSArray(const JSValues &v) : JSObject(ArrayPrototypeObject), elements(v) { setClass(ArrayString); }
uint32 length()
{
@@ -466,6 +473,7 @@ namespace JSTypes {
class JSException : public gc_base {
public:
JSException(String &mess) : value(JSValue(new JSString(mess))) { }
JSException(char *mess) : value(JSValue(new JSString(mess))) { }
JSException(JSValue v) : value(v) { }
JSValue value;
@@ -669,6 +677,7 @@ namespace JSTypes {
bool getValue() { return mValue; }
};
} /* namespace JSTypes */
} /* namespace JavaScript */