pjs/js2/src/js2op_literal.cpp

211 строки
6.8 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the JavaScript 2 Prototype.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU Public License (the "GPL"), in which case the
* provisions of the GPL are applicable instead of those above.
* If you wish to allow use of your version of this file only
* under the terms of the GPL and not to allow others to use your
* version of this file under the NPL, indicate your decision by
* deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete
* the provisions above, a recipient may use your version of this
* file under either the NPL or the GPL.
*/
case eNumber:
{
pushNumber(BytecodeContainer::getFloat64(pc));
pc += sizeof(float64);
}
break;
case eInteger:
{
push(INT_TO_JS2VAL(BytecodeContainer::getInt32(pc)));
pc += sizeof(int32);
}
break;
case eUInt64:
{
pushULong(BytecodeContainer::getUInt64(pc));
pc += sizeof(uint64);
}
break;
case eInt64:
{
pushLong(BytecodeContainer::getInt64(pc));
pc += sizeof(int64);
}
break;
case eTrue:
{
push(JS2VAL_TRUE);
}
break;
case eFalse:
{
push(JS2VAL_FALSE);
}
break;
case eString:
{
uint16 index = BytecodeContainer::getShort(pc);
push(STRING_TO_JS2VAL(allocString(&bCon->mStringList[index])));
pc += sizeof(short);
}
break;
case eRegExp:
{
RegExpInstance *x = checked_cast<RegExpInstance *>(bCon->mObjectList[BytecodeContainer::getShort(pc)]);
push(OBJECT_TO_JS2VAL(x));
pc += sizeof(short);
}
break;
case eFunction:
{
FunctionInstance *x = checked_cast<FunctionInstance *>(bCon->mObjectList[BytecodeContainer::getShort(pc)]);
push(OBJECT_TO_JS2VAL(x));
pc += sizeof(short);
}
break;
case eClosure:
{
FunctionInstance *x = checked_cast<FunctionInstance *>(bCon->mObjectList[BytecodeContainer::getShort(pc)]);
pc += sizeof(short);
// For each active plural frame in the function definition environment, we need
// to find it's current singular counterpart and use that as the dohickey
FrameListIterator closure_fi = x->fWrap->env->getBegin();
FrameListIterator current_fi = meta->env->getBegin();
while (true) {
Frame *closure_fr = *closure_fi;
Frame *current_fr = *current_fi;
ASSERT(closure_fr->kind == current_fr->kind);
if ((closure_fr->kind == ClassKind) || (closure_fr->kind == PackageKind) || (closure_fr->kind == SystemKind))
break;
closure_fi++;
current_fi++;
}
x->fWrap->env = new (meta) Environment(meta->env);
}
break;
case eNull:
{
push(JS2VAL_NULL);
}
break;
case eUndefined:
{
push(JS2VAL_UNDEFINED);
}
break;
case eThis: // XXX literal?
{
pFrame = meta->env->getEnclosingParameterFrame(&a);
if ((pFrame == NULL) || JS2VAL_IS_INACCESSIBLE(a) || JS2VAL_IS_NULL(a))
a = OBJECT_TO_JS2VAL(meta->env->getPackageFrame());
// meta->reportError(Exception::compileExpressionError, "'this' not available", errorPos());
// else
// a = pFrame->thisObject;
push(a);
pFrame = NULL;
}
break;
case eSuper: // XXX literal?
{
pFrame = meta->env->getEnclosingParameterFrame(&a);
ASSERT(pFrame);
// a = pFrame->thisObject;
if (JS2VAL_IS_INACCESSIBLE(a))
meta->reportError(Exception::compileExpressionError, "'this' not available for 'super'", errorPos());
makeLimitedInstance:
{
JS2Class *limit = meta->env->getEnclosingClass()->super;
ASSERT(limit);
a = limit->ImplicitCoerce(meta, a);
ASSERT(JS2VAL_IS_OBJECT(a));
if (JS2VAL_IS_NULL(a))
push(JS2VAL_NULL);
else
push(OBJECT_TO_JS2VAL(new (meta) LimitedInstance(JS2VAL_TO_OBJECT(a), limit)));
}
pFrame = NULL;
}
break;
case eSuperExpr: // XXX literal?
{
a = pop();
goto makeLimitedInstance;
}
break;
case eNewObject:
{
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
SimpleInstance *sInst = new (meta) SimpleInstance(meta, OBJECT_TO_JS2VAL(meta->objectClass->prototype), meta->objectClass);
baseVal = OBJECT_TO_JS2VAL(sInst);
for (uint16 i = 0; i < argCount; i++) {
a = pop();
ASSERT(JS2VAL_IS_STRING(a));
astr = JS2VAL_TO_STRING(a);
b = pop();
meta->createDynamicProperty(sInst, meta->world.identifiers[*astr], b, ReadWriteAccess, false, true);
}
push(baseVal);
baseVal = JS2VAL_VOID;
astr = NULL;
}
break;
case eNewArray:
{
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
ArrayInstance *aInst = new (meta) ArrayInstance(meta, OBJECT_TO_JS2VAL(meta->arrayClass->prototype), meta->arrayClass);
baseVal = OBJECT_TO_JS2VAL(aInst);
for (uint16 i = 0; i < argCount; i++) {
b = pop();
meta->createDynamicProperty(aInst, numberToStringAtom(toUInt32((argCount - 1) - i)), b, ReadWriteAccess, false, true);
}
setLength(meta, aInst, argCount);
push(baseVal);
baseVal = JS2VAL_VOID;
}
break;