зеркало из https://github.com/mozilla/gecko-dev.git
Function & Array prototype fixes. InstanceOf implementation.
This commit is contained in:
Родитель
10603fb685
Коммит
50190e0cda
|
@ -76,7 +76,7 @@ js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 length)
|
|||
|
||||
js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *argv, uint32 argc)
|
||||
{
|
||||
js2val thatValue = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass));
|
||||
js2val thatValue = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(thatValue));
|
||||
if (argc > 0) {
|
||||
if (argc == 1) {
|
||||
|
@ -107,7 +107,9 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *
|
|||
|
||||
static js2val Array_toString(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
|
||||
{
|
||||
if (meta->objectType(thisValue) != meta->arrayClass)
|
||||
if (!JS2VAL_IS_OBJECT(thisValue)
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->arrayClass))
|
||||
meta->reportError(Exception::typeError, "Array.prototype.toString called on a non Array", meta->engine->errorPos());
|
||||
|
||||
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
|
@ -137,7 +139,9 @@ static js2val Array_toString(JS2Metadata *meta, const js2val thisValue, js2val *
|
|||
|
||||
static js2val Array_toSource(JS2Metadata *meta, const js2val thisValue, js2val * /*argv*/, uint32 /*argc*/)
|
||||
{
|
||||
if (meta->objectType(thisValue) != meta->arrayClass)
|
||||
if (!JS2VAL_IS_OBJECT(thisValue)
|
||||
|| (JS2VAL_TO_OBJECT(thisValue)->kind != PrototypeInstanceKind)
|
||||
|| ((checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(thisValue)))->type != meta->arrayClass))
|
||||
meta->reportError(Exception::typeError, "Array.prototype.toString called on a non Array", meta->engine->errorPos());
|
||||
|
||||
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(thisValue));
|
||||
|
@ -204,7 +208,7 @@ js2val Array_concat(JS2Metadata *meta, const js2val thisValue, js2val *argv, uin
|
|||
{
|
||||
js2val E = thisValue;
|
||||
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass));
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
|
||||
uint32 n = 0;
|
||||
uint32 i = 0;
|
||||
|
@ -354,7 +358,7 @@ static js2val Array_slice(JS2Metadata *meta, const js2val thisValue, js2val *arg
|
|||
ASSERT(JS2VAL_IS_OBJECT(thisValue));
|
||||
JS2Object *thisObj = JS2VAL_TO_OBJECT(thisValue);
|
||||
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass));
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
|
||||
|
||||
uint32 length = getLength(meta, thisObj);
|
||||
|
@ -580,7 +584,7 @@ static js2val Array_splice(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
|||
JS2Object *thisObj = JS2VAL_TO_OBJECT(thisValue);
|
||||
uint32 length = getLength(meta, thisObj);
|
||||
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass));
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
|
||||
|
||||
int32 arg0 = meta->toInteger(argv[0]);
|
||||
|
@ -803,6 +807,15 @@ void initArrayObject(JS2Metadata *meta)
|
|||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
||||
meta->arrayClass->construct = Array_Constructor;
|
||||
meta->arrayClass->prototype = new ArrayInstance(meta->objectClass->prototype, meta->arrayClass);
|
||||
|
||||
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
|
||||
meta->env->addFrame(meta->arrayClass);
|
||||
Variable *v = new Variable(meta->arrayClass, OBJECT_TO_JS2VAL(meta->arrayClass->prototype), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
v = new Variable(meta->numberClass, INT_TO_JS2VAL(1), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
PrototypeFunction *pf = &arrayProtos[0];
|
||||
while (pf->name) {
|
||||
|
|
|
@ -488,6 +488,7 @@ namespace MetaData {
|
|||
{ eNew, "New", U16 }, // <argCount:u16>
|
||||
{ eCall, "Call", U16 }, // <argCount:u16>
|
||||
{ eTypeof, "Typeof", 0 },
|
||||
{ eInstanceof, "Instanceof", 0 },
|
||||
{ eIs, "Is", 0 },
|
||||
|
||||
{ ePopv, "Popv", 0 },
|
||||
|
@ -633,6 +634,7 @@ namespace MetaData {
|
|||
return 0;
|
||||
|
||||
case eIs: // pop expr, pop type, push boolean
|
||||
case eInstanceof:
|
||||
return 1;
|
||||
|
||||
case eCoerce: // pop value, push coerced value (type is arg)
|
||||
|
|
|
@ -128,6 +128,7 @@ enum JS2Op {
|
|||
eNew, // <argCount:u16>
|
||||
eCall, // <argCount:u16>
|
||||
eTypeof,
|
||||
eInstanceof,
|
||||
eIs,
|
||||
|
||||
ePopv,
|
||||
|
|
|
@ -57,35 +57,35 @@ namespace MetaData {
|
|||
|
||||
js2val Function_Constructor(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc)
|
||||
{
|
||||
if (argc) {
|
||||
const String &srcLoc = widenCString("Function constructor source");
|
||||
const String *bodyStr = meta->toString(argv[argc - 1]);
|
||||
String functionExpr(widenCString("("));
|
||||
if (argc > 1) {
|
||||
for (uint32 i = 0; i < (argc - 1); i++) {
|
||||
functionExpr += *meta->toString(argv[i]);
|
||||
if (i < (argc - 2))
|
||||
functionExpr += ",";
|
||||
}
|
||||
}
|
||||
functionExpr += widenCString("){") + *bodyStr + widenCString("}");
|
||||
if (argc) {
|
||||
const String &srcLoc = widenCString("Function constructor source");
|
||||
const String *bodyStr = meta->toString(argv[argc - 1]);
|
||||
String functionExpr(widenCString("("));
|
||||
if (argc > 1) {
|
||||
for (uint32 i = 0; i < (argc - 1); i++) {
|
||||
functionExpr += *meta->toString(argv[i]);
|
||||
if (i < (argc - 2))
|
||||
functionExpr += ",";
|
||||
}
|
||||
}
|
||||
functionExpr += widenCString("){") + *bodyStr + widenCString("}");
|
||||
|
||||
Arena a;
|
||||
Pragma::Flags flags = Pragma::js1; // XXX get flags from meta/context ?
|
||||
Parser parser(meta->world, a, flags, functionExpr, srcLoc);
|
||||
Arena a;
|
||||
Pragma::Flags flags = Pragma::js1; // XXX get flags from meta/context ?
|
||||
Parser parser(meta->world, a, flags, functionExpr, srcLoc);
|
||||
FunctionExprNode *fnExpr = parser.parseFunctionExpression(meta->engine->errorPos());
|
||||
ASSERT(parser.lexer.peek(true).hasKind(Token::end));
|
||||
ASSERT(fnExpr); // otherwise, an exception would have been thrown out of here
|
||||
JS2Class *exprType;
|
||||
meta->ValidateExpression(&meta->cxt, meta->env, fnExpr);
|
||||
meta->SetupExprNode(meta->env, RunPhase, fnExpr, &exprType);
|
||||
ASSERT(parser.lexer.peek(true).hasKind(Token::end));
|
||||
ASSERT(fnExpr); // otherwise, an exception would have been thrown out of here
|
||||
JS2Class *exprType;
|
||||
meta->ValidateExpression(&meta->cxt, meta->env, fnExpr);
|
||||
meta->SetupExprNode(meta->env, RunPhase, fnExpr, &exprType);
|
||||
ASSERT(fnExpr);
|
||||
return OBJECT_TO_JS2VAL(fnExpr->obj);
|
||||
}
|
||||
}
|
||||
else { // construct an empty function wrapper
|
||||
js2val thatValue = OBJECT_TO_JS2VAL(new FunctionInstance(meta->functionClass->prototype, meta->functionClass));
|
||||
FunctionInstance *fnInst = checked_cast<FunctionInstance *>(JS2VAL_TO_OBJECT(thatValue));
|
||||
fnInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true));
|
||||
fnInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true));
|
||||
return thatValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1593,6 +1593,8 @@ namespace MetaData {
|
|||
case ExprNode::logicalAndEquals:
|
||||
case ExprNode::logicalXorEquals:
|
||||
case ExprNode::logicalOrEquals:
|
||||
case ExprNode::comma:
|
||||
case ExprNode::Instanceof:
|
||||
|
||||
{
|
||||
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
|
||||
|
@ -1656,19 +1658,12 @@ namespace MetaData {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case ExprNode::comma:
|
||||
case ExprNode::functionLiteral:
|
||||
{
|
||||
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
|
||||
ValidateExpression(cxt, env, b->op1);
|
||||
ValidateExpression(cxt, env, b->op2);
|
||||
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
||||
f->obj = validateStaticFunction(&f->function, JS2VAL_INACCESSIBLE, true, true, cxt, env);
|
||||
}
|
||||
break;
|
||||
case ExprNode::functionLiteral:
|
||||
{
|
||||
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
||||
f->obj = validateStaticFunction(&f->function, JS2VAL_INACCESSIBLE, true, true, cxt, env);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Not Yet Implemented");
|
||||
} // switch (p->getKind())
|
||||
|
@ -2273,9 +2268,19 @@ doUnary:
|
|||
SetupExprNode(env, phase, b->op2, exprType);
|
||||
}
|
||||
break;
|
||||
case ExprNode::Instanceof:
|
||||
{
|
||||
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
|
||||
Reference *rVal = SetupExprNode(env, phase, b->op1, exprType);
|
||||
if (rVal) rVal->emitReadBytecode(bCon, p->pos);
|
||||
rVal = SetupExprNode(env, phase, b->op2, exprType);
|
||||
if (rVal) rVal->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eInstanceof, p->pos);
|
||||
}
|
||||
break;
|
||||
case ExprNode::functionLiteral:
|
||||
{
|
||||
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
||||
{
|
||||
FunctionExprNode *f = checked_cast<FunctionExprNode *>(p);
|
||||
CompilationData *oldData = startCompilationUnit(f->function.fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
|
||||
env->addFrame(f->function.fWrap->compileFrame);
|
||||
SetupStmt(env, phase, f->function.body);
|
||||
|
@ -2283,8 +2288,8 @@ doUnary:
|
|||
bCon->emitOp(eReturnVoid, p->pos);
|
||||
env->removeTopFrame();
|
||||
restoreCompilationUnit(oldData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Not Yet Implemented");
|
||||
}
|
||||
|
@ -3293,9 +3298,8 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
//
|
||||
// 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);
|
||||
|
@ -4628,7 +4632,7 @@ deleteClassProperty:
|
|||
ParameterFrame *plural = checked_cast<ParameterFrame *>(pluralFrame);
|
||||
ASSERT((plural->positionalCount == 0) || (plural->positional != NULL));
|
||||
|
||||
js2val argumentsVal = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass));
|
||||
js2val argumentsVal = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(argumentsVal));
|
||||
uint32 i;
|
||||
for (i = 0; ((i < argCount) && (i < plural->positionalCount)); i++) {
|
||||
|
|
|
@ -579,7 +579,7 @@ public:
|
|||
|
||||
JS2Object *parent; // If this instance was created by calling new on a prototype function,
|
||||
// the value of the function’s prototype property at the time of the call;
|
||||
// none otherwise.
|
||||
// none otherwise. (aka [[prototype]], aka __prototype__)
|
||||
JS2Class *type; // XXX used to determine [[class]] value
|
||||
DynamicPropertyMap dynamicProperties; // A set of this instance's dynamic properties
|
||||
virtual void markChildren();
|
||||
|
@ -639,12 +639,12 @@ public:
|
|||
virtual ~FunctionInstance() { }
|
||||
};
|
||||
|
||||
// Array instances are simple instances created by the Array class, they
|
||||
// Array instances are PrototypeInstances created by the Array class, they
|
||||
// maintain the value of the 'length' property when 'indexable' elements
|
||||
// are added.
|
||||
class ArrayInstance : public SimpleInstance {
|
||||
class ArrayInstance : public PrototypeInstance {
|
||||
public:
|
||||
ArrayInstance(JS2Class *type) : SimpleInstance(type) { }
|
||||
ArrayInstance(JS2Object *parent, JS2Class *type) : PrototypeInstance(parent, type) { }
|
||||
|
||||
virtual void writeProperty(JS2Metadata *meta, const String *name, js2val newValue);
|
||||
virtual ~ArrayInstance() { }
|
||||
|
@ -925,6 +925,7 @@ typedef FrameList::iterator FrameListIterator;
|
|||
class Environment : public JS2Object {
|
||||
public:
|
||||
Environment(SystemFrame *systemFrame, Frame *nextToLast) : JS2Object(EnvironmentKind) { frameList.push_back(nextToLast); frameList.push_back(systemFrame); }
|
||||
virtual ~Environment() { }
|
||||
|
||||
JS2Class *getEnclosingClass();
|
||||
FrameListIterator getRegionalFrame();
|
||||
|
|
|
@ -235,16 +235,86 @@
|
|||
|
||||
case eIs:
|
||||
{
|
||||
a = pop(); // catch variable type
|
||||
b = pop(); // exception object
|
||||
JS2Class *c = meta->objectType(b);
|
||||
if (!JS2VAL_IS_OBJECT(a))
|
||||
b = pop();
|
||||
a = pop(); // doing a is b
|
||||
|
||||
if (!JS2VAL_IS_OBJECT(b))
|
||||
meta->reportError(Exception::badValueError, "Type expected", errorPos());
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(a);
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(b);
|
||||
if (obj->kind != ClassKind)
|
||||
meta->reportError(Exception::badValueError, "Type expected", errorPos());
|
||||
JS2Class *isClass = checked_cast<JS2Class *>(obj);
|
||||
push(c == isClass);
|
||||
push(BOOLEAN_TO_JS2VAL(meta->objectType(a) == isClass));
|
||||
}
|
||||
break;
|
||||
|
||||
case eInstanceof: // XXX prototype version
|
||||
{
|
||||
b = pop();
|
||||
a = pop(); // doing a instanceof b
|
||||
|
||||
if (!JS2VAL_IS_OBJECT(b))
|
||||
meta->reportError(Exception::typeError, "Object expected for instanceof", errorPos());
|
||||
JS2Object *obj = JS2VAL_TO_OBJECT(b);
|
||||
if ((obj->kind == PrototypeInstanceKind)
|
||||
&& (checked_cast<PrototypeInstance *>(obj)->type == meta->functionClass)) {
|
||||
// XXX this is [[hasInstance]] from ECMA3
|
||||
if (!JS2VAL_IS_OBJECT(a))
|
||||
push(JS2VAL_FALSE);
|
||||
else {
|
||||
if (JS2VAL_TO_OBJECT(a)->kind != PrototypeInstanceKind)
|
||||
meta->reportError(Exception::typeError, "PrototypeInstance expected for instanceof", errorPos());
|
||||
JS2Object *a_protoObj = checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(a))->parent;
|
||||
|
||||
js2val b_protoVal;
|
||||
JS2Object *b_protoObj = NULL;
|
||||
Multiname mn(prototype_StringAtom); // gc safe because the content is rooted elsewhere
|
||||
LookupKind lookup(true, JS2VAL_NULL); // make it a lexical lookup since we want it to
|
||||
// fail if 'prototype' hasn't been defined
|
||||
// XXX (prototype should always exist for functions)
|
||||
if (meta->readProperty(&a, &mn, &lookup, RunPhase, &b_protoVal)) {
|
||||
if (!JS2VAL_IS_OBJECT(b_protoVal))
|
||||
meta->reportError(Exception::typeError, "Non-object prototype value in instanceOf", errorPos());
|
||||
b_protoObj = JS2VAL_TO_OBJECT(b_protoVal);
|
||||
}
|
||||
bool result = false;
|
||||
while (a_protoObj) {
|
||||
if (b_protoObj == a_protoObj) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
a_protoObj = checked_cast<PrototypeInstance *>(a_protoObj)->parent;
|
||||
}
|
||||
push(BOOLEAN_TO_JS2VAL(result));
|
||||
}
|
||||
}
|
||||
else { // XXX also support a instanceof <<class>> since some of these are
|
||||
// the ECMA3 builtins.
|
||||
if (obj->kind == ClassKind) {
|
||||
if (!JS2VAL_IS_OBJECT(a))
|
||||
push(JS2VAL_FALSE);
|
||||
else {
|
||||
if (JS2VAL_TO_OBJECT(a)->kind != PrototypeInstanceKind)
|
||||
meta->reportError(Exception::typeError, "PrototypeInstance expected for instanceof", errorPos());
|
||||
JS2Object *a_protoObj = checked_cast<PrototypeInstance *>(JS2VAL_TO_OBJECT(a))->parent;
|
||||
|
||||
JS2Object *b_protoObj = checked_cast<JS2Class *>(obj)->prototype;
|
||||
|
||||
bool result = false;
|
||||
while (a_protoObj) {
|
||||
if (b_protoObj == a_protoObj) {
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
a_protoObj = checked_cast<PrototypeInstance *>(a_protoObj)->parent;
|
||||
}
|
||||
push(BOOLEAN_TO_JS2VAL(result));
|
||||
}
|
||||
}
|
||||
else
|
||||
meta->reportError(Exception::typeError, "Function or Class expected in instanceOf", errorPos());
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -135,12 +135,12 @@
|
|||
{
|
||||
uint16 argCount = BytecodeContainer::getShort(pc);
|
||||
pc += sizeof(uint16);
|
||||
ArrayInstance *aInst = new ArrayInstance(meta->arrayClass);
|
||||
ArrayInstance *aInst = new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass);
|
||||
baseVal = OBJECT_TO_JS2VAL(aInst);
|
||||
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);
|
||||
|
|
|
@ -142,7 +142,7 @@ namespace MetaData {
|
|||
|
||||
REMatchState *match = REExecute(thisInst->mRegExp, str->begin(), index, toInt32(str->length()), meta->toBoolean(globalMultiline));
|
||||
if (match) {
|
||||
PrototypeInstance *A = new PrototypeInstance(meta->objectClass->prototype, meta->objectClass);
|
||||
PrototypeInstance *A = new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass);
|
||||
result = OBJECT_TO_JS2VAL(A);
|
||||
js2val matchStr = meta->engine->allocString(str->substr((uint32)match->startIndex, (uint32)match->endIndex - match->startIndex));
|
||||
Multiname mname(&meta->world.identifiers[*meta->toString((long)0)], meta->publicNamespace);
|
||||
|
|
|
@ -170,7 +170,7 @@ static js2val String_match(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
|||
return RegExp_exec(meta, regexp, &S, 1);
|
||||
}
|
||||
else {
|
||||
PrototypeInstance *A = new PrototypeInstance(meta->objectClass->prototype, meta->objectClass);
|
||||
PrototypeInstance *A = new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass);
|
||||
int32 index = 0;
|
||||
int32 lastIndex = 0;
|
||||
while (true) {
|
||||
|
@ -405,7 +405,7 @@ static js2val String_split(JS2Metadata *meta, const js2val thisValue, js2val *ar
|
|||
{
|
||||
const String *S = meta->toString(thisValue);
|
||||
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass));
|
||||
js2val result = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass->prototype, meta->arrayClass));
|
||||
ArrayInstance *A = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(result));
|
||||
|
||||
uint32 lim;
|
||||
|
|
Загрузка…
Ссылка в новой задаче