/* -*- 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(bCon->mObjectList[BytecodeContainer::getShort(pc)]); push(OBJECT_TO_JS2VAL(x)); pc += sizeof(short); } break; case eFunction: { FunctionInstance *x = checked_cast(bCon->mObjectList[BytecodeContainer::getShort(pc)]); push(OBJECT_TO_JS2VAL(x)); pc += sizeof(short); } break; case eClosure: { FunctionInstance *x = checked_cast(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;