U32 ObjectDeclNode::compileSubObject(U32 *codeStream, U32 ip, bool root) { U32 start = ip; codeStream[ip++] = OP_PUSH_FRAME; ip = classNameExpr->compile(codeStream, ip, TypeReqString); codeStream[ip++] = OP_PUSH; ip = objectNameExpr->compile(codeStream, ip, TypeReqString); codeStream[ip++] = OP_PUSH; for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext()) { ip = exprWalk->compile(codeStream, ip, TypeReqString); codeStream[ip++] = OP_PUSH; } codeStream[ip++] = OP_CREATE_OBJECT; codeStream[ip] = STEtoU32(parentObject, ip); ip++; codeStream[ip++] = isDatablock; codeStream[ip++] = isClassNameInternal; codeStream[ip++] = isSingleton; codeStream[ip++] = dbgLineNumber; codeStream[ip++] = start + failOffset; for(SlotAssignNode *slotWalk = slotDecls; slotWalk; slotWalk = (SlotAssignNode *) slotWalk->getNext()) ip = slotWalk->compile(codeStream, ip, TypeReqNone); codeStream[ip++] = OP_ADD_OBJECT; codeStream[ip++] = root; for(ObjectDeclNode *objectWalk = subObjects; objectWalk; objectWalk = (ObjectDeclNode *) objectWalk->getNext()) ip = objectWalk->compileSubObject(codeStream, ip, false); codeStream[ip++] = OP_END_OBJECT; codeStream[ip++] = root || isDatablock; // Added to fix the object creation issue [7/9/2007 Black] codeStream[ip++] = OP_FINISH_OBJECT; return ip; }
U32 ObjectDeclNode::precompileSubObject(bool) { // goes // OP_PUSHFRAME 1 // name expr // OP_PUSH 1 // args... PUSH // OP_CREATE_OBJECT 1 // parentObject 1 // isDatablock 1 // internalName 1 // isSingleton 1 // lineNumber 1 // fail point 1 // for each field, eval // OP_ADD_OBJECT (to UINT[0]) 1 // root? 1 // add all the sub objects. // OP_END_OBJECT 1 // root? 1 // To fix the stack issue [7/9/2007 Black] // OP_FINISH_OBJECT <-- fail point jumps to this opcode U32 argSize = 0; precompileIdent(parentObject); for(ExprNode *exprWalk = argList; exprWalk; exprWalk = (ExprNode *) exprWalk->getNext()) argSize += exprWalk->precompile(TypeReqString) + 1; argSize += classNameExpr->precompile(TypeReqString) + 1; U32 nameSize = objectNameExpr->precompile(TypeReqString) + 1; U32 slotSize = 0; for(SlotAssignNode *slotWalk = slotDecls; slotWalk; slotWalk = (SlotAssignNode *) slotWalk->getNext()) slotSize += slotWalk->precompile(TypeReqNone); // OP_ADD_OBJECT U32 subObjSize = 0; for(ObjectDeclNode *objectWalk = subObjects; objectWalk; objectWalk = (ObjectDeclNode *) objectWalk->getNext()) subObjSize += objectWalk->precompileSubObject(false); failOffset = 12 + nameSize + argSize + slotSize + subObjSize; // +1 because the failOffset should jump to OP_FINISH_OBJECT [7/9/2007 Black] return failOffset + 1; }
U32 FuncCallExprNode::precompile(TypeReq type) { // OP_PUSH_FRAME // arg OP_PUSH arg OP_PUSH arg OP_PUSH // eval all the args, then call the function. // OP_CALLFUNC // function // namespace // isDot U32 size = 0; if(type != TypeReqString) size++; precompileIdent(funcName); precompileIdent(nameSpace); for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext()) size += walk->precompile(TypeReqString) + 1; return size + 5; }
U32 FuncCallExprNode::compile(U32 *codeStream, U32 ip, TypeReq type) { codeStream[ip++] = OP_PUSH_FRAME; for(ExprNode *walk = args; walk; walk = (ExprNode *) walk->getNext()) { ip = walk->compile(codeStream, ip, TypeReqString); codeStream[ip++] = OP_PUSH; } if(callType == MethodCall || callType == ParentCall) codeStream[ip++] = OP_CALLFUNC; else codeStream[ip++] = OP_CALLFUNC_RESOLVE; codeStream[ip] = STEtoU32(funcName, ip); ip++; codeStream[ip] = STEtoU32(nameSpace, ip); ip++; codeStream[ip++] = callType; if(type != TypeReqString) codeStream[ip++] = conversionOp(TypeReqString, type); return ip; }