Beispiel #1
0
Atom Stubs::do_abc_callsupernsx(MethodFrame* f, const Multiname* name, Atom ns,
                                Atom index, int argc, Atom* args) {
  Multiname tempname;
  MethodEnv* e = env(f);
  initnamensx(e, name, ns, index, &tempname);
  return e->callsuper(&tempname, argc - 1, args);
}
Beispiel #2
0
BoolKind Stubs::do_abc_deletepropns(MethodFrame* f, const Multiname* name,
                                    Atom ns, Atom object) {
  Multiname tempname;
  MethodEnv* e = env(f);
  initnamens(e, name, ns, &tempname);
  return boolKind(e->delproperty(object, &tempname) == trueAtom);
}
Beispiel #3
0
void Stubs::do_abc_setsupernsx(MethodFrame* f, const Multiname* name, Atom ns,
                               Atom index, Atom object, Atom value) {
  Multiname tempname;
  MethodEnv* e = env(f);
  initnamensx(e, name, ns, index, &tempname);
  e->setsuper(object, &tempname, value);
}
Beispiel #4
0
void Stubs::do_abc_initpropnsx(MethodFrame* f, const Multiname* name, Atom ns,
                               Atom index, Atom object, Atom value) {
  Multiname tempname;
  MethodEnv* e = env(f);
  initnamensx(e, name, ns, index, &tempname);
  e->initproperty(object, &tempname, value, toVTable(e, object));
}
Beispiel #5
0
inline uint8_t* rangeCheck(MethodFrame* f, int32_t addr, size_t bytes) {
  MethodEnv* e = env(f);
  const DomainEnv* d = e->domainEnv();
  if (uint32_t(addr) > (d->globalMemorySize() - bytes))
    avmplus::mop_rangeCheckFailed(e);
  return d->globalMemoryBase() + addr;
}
Beispiel #6
0
Atom Stubs::do_abc_getsupernsx(MethodFrame* f, const Multiname* name, Atom ns,
                               Atom index, Atom object) {
  Multiname tempname;
  MethodEnv* e = env(f);
  initnamensx(e, name, ns, index, &tempname);
  return e->getsuper(object, &tempname);
}
Beispiel #7
0
BoolKind Stubs::do_abc_deletepropnsx(MethodFrame* f, const Multiname* name,
                                     Atom ns, Atom index, Atom object) {
  checkXMLList(f, index);
  Multiname tempname;
  MethodEnv* e = env(f);
  initnamensx(e, name, ns, index, &tempname);
  return boolKind(e->delproperty(object, &tempname) == trueAtom);
}
Beispiel #8
0
	ClassClosure* FunctionClass::createEmptyFunction()
	{
		// invoke AS3 private static function emptyCtor, which returns an empty function.
		TraitsBindingsp t = traits()->getTraitsBindings();
		Binding b = t->findBinding(core()->internConstantStringLatin1("emptyCtor"));
		MethodEnv *f = vtable->methods[AvmCore::bindingToMethodId(b)];
		return (ClassClosure*)AvmCore::atomToScriptObject(f->coerceEnter(this->atom()));
	}
Beispiel #9
0
CodeContext* getClassCodeContext(const ScriptObject* so)
{
    if (!so)
        return NULL;
    if (so->core()->isFunction(so->atom())) {
        AvmAssert(!"Function or MC is not legal here.");
        return NULL;
    }
    avmplus::TraitsPosType t = so->traits()->posType();
    if (t == avmplus::TRAITSTYPE_CATCH || t == avmplus::TRAITSTYPE_ACTIVATION) {
        AvmAssert(!"Activation and Catch objects are not legal here.");
        return NULL;
    }
    MethodEnv* init = so->vtable->init;
    if (!init) {
        AvmAssert(!"init method is null, should not be possible.");
        return NULL;
    }
    return init->scope()->abcEnv()->codeContext();
}
Beispiel #10
0
    /**
     * This function is called by JIT code if OSR has been requested
     * if (exec->current_osr != 0).  This function fills the JIT frame locals
     * to match the interpreter frame.  The JIT code looks like this:
     *
     *   if (*(&exec->current_osr)) {
     *     adjustFrame(...);
     *     goto loop_entry
     *   }
     */
    void OSR::adjustFrame(MethodFrame* jitMethodFrame, CallStackNode *callStack,
                             FramePtr jitFramePointer,  uint8_t *jitFrameTags)
    {
        MethodEnv* env = jitMethodFrame->env();
        BaseExecMgr* exec = BaseExecMgr::exec(env);
        OSR *osr = exec->current_osr;
        AvmAssert(osr && "should not have gotten here");
        Atom* interpFramePointer = osr->interp_frame;

        MethodSignaturep ms = env->method->getMethodSignature();
        int nLocals = ms->local_count();
        int stackBase = nLocals + ms->max_scope();
        FrameState* frameState = osr->jit_frame_state;
        int scopeTop = nLocals + frameState->scopeDepth;
        int stackTop = stackBase + frameState->stackDepth;

        // OSR has been requested.

#ifdef AVMPLUS_VERBOSE
        if (env->method->pool()->isVerbose(VB_interp)) {
            env->core()->console <<
                    "osr-adjust_frame " << env->method->method_id() <<
                    " " << env->method <<
                    " scopeTop=" << scopeTop <<
                    " stackTop=" << stackTop <<
                    "\n";
        }
#endif

        // Patch the JIT frame local variable slots and the scope slots in use to match the interpreter state.
        for (int i = 0; i < scopeTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        // zero out stack area for unused scopes:
        if (scopeTop < stackBase) {
            void* p = ((char*) jitFramePointer + (scopeTop << VARSHIFT(env->method)));
            size_t nbytes = (stackBase - scopeTop) << VARSHIFT(env->method);
            VMPI_memset(p, 0, nbytes);
        }

        // Patch operand stack slots:
        for (int i = stackBase; i < stackTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        MethodFrame *interpreterMethodFrame = jitMethodFrame->next;
        jitMethodFrame->dxns = interpreterMethodFrame->dxns;
        jitMethodFrame->next = interpreterMethodFrame->next;

        // Clean up non-local OSR parameterization data:
        mmfx_delete(frameState);
        exec->current_osr = NULL;

#ifdef DEBUGGER
        // Call debugEnter if necessary, since the jit code won't.
        // We can safely pass NULL for &eip here, because OSR is disabled
        // for methods with catch blocks.
        if (callStack)
            env->debugEnter(jitFrameTags, callStack, jitFramePointer, NULL);
#else
        (void) callStack;
#endif
    }
Beispiel #11
0
void Stubs::do_abc_initprop(MethodFrame* f, const Multiname* name, Atom object,
                            Atom value) {
  MethodEnv* e = env(f);
  e->initproperty(object, name, value, toVTable(e, object));
}
Beispiel #12
0
    /**
     * This function detects if OSR has been requested or if this is a
     * subsequent normal call.  In the latter case it has no side effect and
     * returns false and control flow is supposed to proceed normally.
     * If OSR is in the works, then it fills the JIT frame locals to match the
     * interpreter frame.  Then it returns true, which indicates to the
     * generated code to jump to the OSR entry point.
     *
     * The JIT code looks like this:
     *
     *   if (adjust_frame(...))
     *     goto loop_entry
     */
    int32_t OSR::adjustFrame(MethodFrame* jitMethodFrame,
                             CallStackNode *callStack,
                             FramePtr jitFramePointer,
                             uint8_t *jitFrameTags)
    {
        MethodEnv* env = jitMethodFrame->env();
        BaseExecMgr* exec = BaseExecMgr::exec(env);
        OSR *osr = exec->current_osr;
        if (!osr) {
            // No OSR has been requested.
            // We are at the beginning of a normal AS method call.
            // Indicate proceeding with normal control flow.
            return 0;
        }
        Atom* interpFramePointer = osr->interp_frame;

        MethodSignaturep ms = env->method->getMethodSignature();
        int nLocals = ms->local_count();
        int stackBase = nLocals + ms->max_scope();
        FrameState* frameState = osr->jit_frame_state;
        int scopeTop = nLocals + frameState->scopeDepth;
        int stackTop = stackBase + frameState->stackDepth;

        // OSR has been requested.

#ifdef AVMPLUS_VERBOSE
        if (env->method->pool()->isVerbose(VB_interp)) {
            env->core()->console <<
                    "osr-adjust_frame " << env->method->method_id() <<
                    " " << env->method <<
                    " scopeTop=" << scopeTop <<
                    " stackTop=" << stackTop <<
                    "\n";
        }
#endif

        // Patch the JIT frame local variable slots and the scope slots in use to match the interpreter state.
        for (int i = 0; i < scopeTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        // zero out stack area for unused scopes:
        if (scopeTop < stackBase) {
            void* p = ((char*) jitFramePointer + scopeTop * VARSIZE);
            size_t nbytes = (stackBase - scopeTop) * VARSIZE;
            VMPI_memset(p, 0, nbytes);
        }

        // Patch operand stack slots:
        for (int i = stackBase; i < stackTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        MethodFrame *interpreterMethodFrame = jitMethodFrame->next;
        jitMethodFrame->dxns = interpreterMethodFrame->dxns;
        jitMethodFrame->next = interpreterMethodFrame->next;

        // Clean up non-local OSR parameterization data:
        mmfx_delete(frameState);
        exec->current_osr = NULL;

#ifdef DEBUGGER
        // Call debugEnter if necessary, since the jit code won't.
        // We can safely pass NULL for &eip here, because OSR is disabled
        // for methods with catch blocks.
        if (callStack)
            env->debugEnter(jitFrameTags, callStack, jitFramePointer, NULL);
#else
        (void) callStack;
#endif

        // Indicate taking a shortcut from the call site
        // to the OSR entry point instead of normal control flow:
        return 1;
    }
Beispiel #13
0
    double SamplerScript::_getInvocationCount(ScriptObject* self, Atom a, QNameObject* qname, uint32_t type)
    {
#ifdef DEBUGGER
        AvmCore* core = self->core();
        Sampler* s = core->get_sampler();
        if (!s || !trusted(self))
            return -1;

        Multiname multiname;
        if(qname)
            qname->getMultiname(multiname);

        ScriptObject* object = self->toplevel()->global();
        if(!AvmCore::isObject(a))
        {
            // not sure if this will be true for standalone avmplus
            AvmAssert(core->codeContext() != NULL);
            DomainEnv *domainEnv = core->codeContext()->domainEnv();
            ScriptEnv* script = (ScriptEnv*) core->domainMgr()->findScriptEnvInDomainEnvByMultiname(domainEnv, multiname);
            if (script != (ScriptEnv*)BIND_NONE)
            {
                if (script == (ScriptEnv*)BIND_AMBIGUOUS)
                    self->toplevel()->throwReferenceError(kAmbiguousBindingError, &multiname);

                object = script->global;
                if (object == NULL)
                {
                    object = script->initGlobal();
                    script->coerceEnter(script->global->atom());
                }
            }
        }
        else
        {
            object = AvmCore::atomToScriptObject(a);

            if(AvmCore::istype(a, CLASS_TYPE) && !qname) {
                // return constructor count
                ClassClosure *cc = (ClassClosure*)object;
                if (cc->vtable->init) // Vector related crash here, Tommy says: I didn't think a type could ever not have a constructor but I guess there's no reason it has to.
                    return (double)cc->vtable->init->invocationCount();
            }
        }

        if(!object || !qname)
            return -1;

        VTable *v = object->vtable;

    again:

        MethodEnv *env = NULL;
        Binding b = self->toplevel()->getBinding(v->traits, &multiname);
        switch (AvmCore::bindingKind(b))
        {
        case BKIND_VAR:
        case BKIND_CONST:
        {
            // only look at slots for first pass, otherwise we're applying instance traits to the Class
            if(v == object->vtable) {
                Atom method = object->getSlotAtom(AvmCore::bindingToSlotId(b));
                if(AvmCore::isObject(method))
                {
                    env = AvmCore::atomToScriptObject(method)->getCallMethodEnv();
                }
            }
            break;
        }
        case BKIND_METHOD:
        {
            int m = AvmCore::bindingToMethodId(b);
            env = v->methods[m];
            break;
        }
        case BKIND_GET:
        case BKIND_GETSET:
        case BKIND_SET:
        {
            if(type == GET && AvmCore::hasGetterBinding(b))
                env = v->methods[AvmCore::bindingToGetterId(b)];
            else if(type == SET && AvmCore::hasSetterBinding(b))
                env = v->methods[AvmCore::bindingToSetterId(b)];
            break;
        }
        case BKIND_NONE:
        {
            Atom method = object->getStringProperty(multiname.getName());
            if(AvmCore::isObject(method))
            {
                env = AvmCore::atomToScriptObject(method)->getCallMethodEnv();
            }
            else if(v->ivtable)
            {
                v = v->ivtable;
                goto again;
            }
        }
        default:
            break;
        }

        if(env)
            return (double)env->invocationCount();
#else
        (void)self;
        (void)type;
        (void)qname;
        (void)a;
#endif

        return -1;
    }