Mozilla/mozilla/js2/src/js2op_invocation.cpp
rogerl%netscape.com aad802e73e For stmt, block frame & gc work.
git-svn-id: svn://10.0.0.236/trunk@129531 18797224-902f-48f8-a5cc-f745e15eee43
2002-09-13 17:54:16 +00:00

138 lines
4.9 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 eNewObject: // XXX in js2op_literal instead?
{
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
PrototypeInstance *pInst = new PrototypeInstance(NULL); // XXX Object prototype object
for (uint16 i = 0; i < argCount; i++) {
js2val nameVal = pop();
ASSERT(JS2VAL_IS_STRING(nameVal));
String *name = JS2VAL_TO_STRING(nameVal);
const StringAtom &nameAtom = world.identifiers[*name];
js2val fieldVal = pop();
const DynamicPropertyMap::value_type e(nameAtom, fieldVal);
pInst->dynamicProperties.insert(e);
}
push(OBJECT_TO_JS2VAL(pInst));
}
break;
/*
case eToBoolean:
{
js2val v = pop();
bool b = toBoolean(v);
retval = BOOLEAN_TO_JS2VAL(b);
push(retval);
}
break;
*/
case eNew:
{
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
js2val v = top();
ASSERT(JS2VAL_IS_OBJECT(v) && !JS2VAL_IS_NULL(v));
JS2Object *obj = JS2VAL_TO_OBJECT(v);
ASSERT(obj->kind == ClassKind);
JS2Class *c = checked_cast<JS2Class *>(obj);
push(OBJECT_TO_JS2VAL(c->construct(this)));
}
break;
case eCall:
{
uint16 argCount = BytecodeContainer::getShort(pc);
pc += sizeof(uint16);
js2val thisVal = top(argCount + 1);
js2val fVal = top(argCount);
if (JS2VAL_IS_PRIMITIVE(fVal))
meta->reportError(Exception::badValueError, "Can't call on primitive value", errorPos());
JS2Object *fObj = JS2VAL_TO_OBJECT(fVal);
if (fObj->kind == FixedInstanceKind) {
FixedInstance *fInst = checked_cast<FixedInstance *>(fObj);
FunctionWrapper *fWrap = fInst->fWrap;
js2val compileThis = fWrap->compileFrame->thisObject;
js2val runtimeThis;
if (JS2VAL_IS_VOID(compileThis))
runtimeThis = JS2VAL_VOID;
else {
if (JS2VAL_IS_INACCESSIBLE(compileThis)) {
runtimeThis = thisVal;
Frame *g = meta->env.getPackageOrGlobalFrame();
if (fWrap->compileFrame->prototype && (JS2VAL_IS_NULL(runtimeThis) || JS2VAL_IS_VOID(runtimeThis)) && (g->kind == GlobalObjectKind))
runtimeThis = OBJECT_TO_JS2VAL(g);
}
}
Frame *runtimeFrame = new ParameterFrame(fWrap->compileFrame);
meta->env.addFrame(runtimeFrame);
runtimeFrame->instantiate(&meta->env);
// assignArguments(runtimeFrame, fWrap->compileFrame->signature);
jsr(fWrap->bCon);
}
else
ASSERT(false);
}
break;
case ePopv:
{
retval = pop();
}
break;
case eReturn:
{
retval = pop();
if (activationStackEmpty())
return retval;
else
rts();
}
break;
case eReturnVoid:
{
if (activationStackEmpty())
return retval;
else
rts();
}
break;