void X86SubProgram::declareParam(const string& param, int type, int msize) { if(msize == 0) { _head << "%define " << X86::makeID(param) << " ebp+" << _param_offset << endl; _end << "%undef " << X86::makeID(param) << endl; } else { _head << "%define _p_" << X86::makeID(param) << " ebp+" << _param_offset << endl; _end << "%undef _p_" << X86::makeID(param) << endl; declareLocal(param, msize, false); writeMatrixCopyCode(param, type, msize); } _param_offset -= SizeofDWord; }
// Dispatch. as_value Function::call(const fn_call& fn) { // Extract caller before pushing ourself on the call stack VM& vm = getVM(fn); as_object* caller = vm.calling() ? &vm.currentCall().function() : 0; // Set up local stack frame, for parameters and locals. FrameGuard guard(getVM(fn), *this); CallFrame& cf = guard.callFrame(); DisplayObject* target = _env.target(); DisplayObject* orig_target = _env.get_original_target(); // Some features are version-dependant. const int swfversion = getSWFVersion(fn); if (swfversion < 6) { // In SWF5, when 'this' is a DisplayObject it becomes // the target for this function call. // See actionscript.all/setProperty.as DisplayObject* ch = get<DisplayObject>(fn.this_ptr); if (ch) { target = ch; orig_target = ch; } } /// This is only needed for SWF5 (temp switch of target) /// We do always and base 'target' value on SWF version. /// TODO: simplify code by maybe using a custom as_environment /// instead, so to get an "original" target being /// the one set now (rather then the really original one) /// TODO: test scope when calling functions defined in another timeline /// (target, in particular). TargetGuard targetGuard(_env, target, orig_target); // Push the arguments onto the local frame. for (size_t i = 0, n = _args.size(); i < n; ++i) { assert(_args[i].reg == 0); if (i < fn.nargs) { setLocal(cf, _args[i].name, fn.arg(i)); } else { // Still declare named arguments, even if // they are not passed from caller // See bug #22203 declareLocal(cf, _args[i].name); } } // Add 'this' setLocal(cf, NSV::PROP_THIS, fn.this_ptr ? fn.this_ptr : as_value()); as_object* super = fn.super ? fn.super : fn.this_ptr ? fn.this_ptr->get_super() : 0; // Add 'super' (SWF6+ only) if (super && swfversion > 5) { setLocal(cf, NSV::PROP_SUPER, super); } // Add 'arguments' as_object* args = getGlobal(fn).createArray(); // Put 'arguments' in a local var. setLocal(cf, NSV::PROP_ARGUMENTS, getArguments(*this, *args, fn, caller)); // Execute the actions. as_value result; ActionExec(*this, _env, &result, fn.this_ptr)(); return result; }