예제 #1
0
/* This is the fast non-tracing interpreter.*/
void fnt_InnerExecute(register fnt_LocalGraphicStateType *gs, tt_uint8 *ptr, tt_uint8 *eptr)
{
    register FntFunc* function;
    tt_uint8 *oldInsPtr = gs->insPtr;
    tt_uint8 *oldEndPtr = gs->endPtr;
    tt_uint8 *oldBasePtr = gs->basePtr;
    gs->insPtr = ptr;
    gs->endPtr = eptr;
    gs->basePtr = ptr;
    
    function = gs->globalGS->function;
#ifdef really_slow_debugging
    CHECK_STATE( gs );
#endif
    while(gs->insPtr < eptr && gs->insPtr >= gs->basePtr) {
			
#ifdef record_opCodes
      opCodeCounter[*gs->insPtr]++;
#endif
      function[ gs->opCode = *gs->insPtr++ ]( gs );
#ifdef really_slow_debugging
      CHECK_STATE( gs );
#endif
    }
			
    gs->insPtr = oldInsPtr;
    gs->endPtr = oldEndPtr;
    gs->basePtr = oldBasePtr;
}
예제 #2
0
 int GlfwApplication::Run() {
   CHECK_STATE(glfwInit() != -1);
   glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
   glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
   glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
   glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
   if (minimized) {
     window = glfwCreateWindow(kMinimizedWidth, kMinimizedHeight, title.c_str(), nullptr, nullptr);
   } else {
     window = glfwCreateWindow(width, height, title.c_str(), nullptr, nullptr);
   }
   CHECK_STATE(window != nullptr);
   glfwSetKeyCallback(window, HandleKeyboard);
   glfwSetMouseButtonCallback(window, HandleMouseButton);
   glfwSetFramebufferSizeCallback(window, HandleReshape);
   glfwMakeContextCurrent(window);
   glfwSwapInterval(1);
   std::cout << glGetString(GL_VERSION) << std::endl;
   std::cout << glfwGetJoystickName(GLFW_JOYSTICK_1) << std::endl;
   renderer.Create();
   int framebuffer_width, framebuffer_height;
   glfwGetFramebufferSize(window, &framebuffer_width, &framebuffer_height);
   HandleReshape(window, framebuffer_width, framebuffer_height);
   controller.Setup();
   while (!glfwWindowShouldClose(window)) {
     if (keyboard.GetKeyVelocity(GLFW_KEY_TAB) > 0) {
       if (minimized) {
         glfwSetWindowSize(window, width, height);
         glfwShowWindow(window);
       } else {
         glfwHideWindow(window);
         glfwSetWindowSize(window, kMinimizedWidth, kMinimizedHeight);
       }
       minimized = !minimized;
     }
     if (minimized) {
       glClearColor(1.0, 1.0, 1.0, 1.0);
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     } else {
       renderer.Render();
     }
     controller.Update();
     keyboard.Update();
     mouse.Update();
     double x, y;
     glfwGetCursorPos(window, &x, &y);
     mouse.OnCursorMove(glm::vec2(x, y));
     joystick.Update();
     input.Update();
     glfwSwapBuffers(window);
     glfwPollEvents();
     if (minimized) {
       usleep(16666);
     }
   }
   glfwTerminate();
   return 0;
 }
  void TextEngineRenderer::Create() {
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    if (edit) {
      MaybeRebuildAttenuationShader();
    }
    
    vertex_shader.Create(GL_VERTEX_SHADER, {kVertexShaderSource});
    fragment_shader.Create(GL_FRAGMENT_SHADER, {kFragmentShaderSource});
    face_program.Create({&vertex_shader, &fragment_shader});
    face_program.CompileAndLink();

    vertex_format.Create({
      {u8"vertex_position", GL_FLOAT, 2}
    });

    unit_circle.data.insert(unit_circle.data.cend(), {
      0.0f, 0.0f
    });
    for (auto i = 0.0f; i < 101.0f; ++i) {
      const auto theta = 2.0f * i / 100.0f * M_PI;
      const auto point = glm::vec2(glm::cos(theta), glm::sin(theta));
      unit_circle.data.insert(unit_circle.data.cend(), {
        point.x, point.y
      });
    }
    unit_circle.element_count = 102;
    unit_circle.element_type = GL_TRIANGLE_FAN;

    unit_square.data.insert(unit_square.data.cend(), {
      0.5f, -0.5f,
      0.5f, 0.5f,
      -0.5f, -0.5f,
      -0.5f, 0.5f
    });
    unit_square.element_count = 4;
    unit_square.element_type = GL_TRIANGLE_STRIP;
    
    circle_buffer.Create(GL_ARRAY_BUFFER);
    circle_buffer.Data(unit_circle.data_size(), unit_circle.data.data(), GL_STATIC_DRAW);
    circle_array.Create();
    vertex_format.Apply(circle_array, face_program);
    CHECK_STATE(!glGetError());

    rectangle_buffer.Create(GL_ARRAY_BUFFER);
    rectangle_buffer.Data(unit_square.data_size(), unit_square.data.data(), GL_STATIC_DRAW);
    rectangle_array.Create();
    vertex_format.Apply(rectangle_array, face_program);
    CHECK_STATE(!glGetError());

    stroke_width = 0.0025f;
    stroke = glm::vec4(0, 0, 0, 1);
    fill = glm::vec4(0.5, 0.5, 0.5, 1);

    CHECK_STATE(imguiRenderGLInit("../resource/fonts/ubuntu-font-family-0.80/Ubuntu-R.ttf"));
  }
예제 #4
0
void
XPCCallContext::SetName(jsid name)
{
    CHECK_STATE(HAVE_OBJECT);

    mName = name;

    if (mTearOff) {
        mSet = nsnull;
        mInterface = mTearOff->GetInterface();
        mMember = mInterface->FindMember(name);
        mStaticMemberIsLocal = true;
        if (mMember && !mMember->IsConstant())
            mMethodIndex = mMember->GetIndex();
    } else {
        mSet = mWrapper ? mWrapper->GetSet() : nsnull;

        if (mSet &&
            mSet->FindMember(name, &mMember, &mInterface,
                             mWrapper->HasProto() ?
                             mWrapper->GetProto()->GetSet() :
                             nsnull,
                             &mStaticMemberIsLocal)) {
            if (mMember && !mMember->IsConstant())
                mMethodIndex = mMember->GetIndex();
        } else {
            mMember = nsnull;
            mInterface = nsnull;
            mStaticMemberIsLocal = false;
        }
    }

    mState = HAVE_NAME;
}
예제 #5
0
void GdbCoreEngine::runEngine()
{
    CHECK_STATE(EngineRunRequested);
    runCommand({"target core " + coreFileName().toLocal8Bit(), NoFlags,
                CB(handleTargetCore)
               });
}
예제 #6
0
void
XPCCallContext::SetCallInfo(XPCNativeInterface* iface, XPCNativeMember* member,
                            JSBool isSetter)
{
    CHECK_STATE(HAVE_CONTEXT);

    // We are going straight to the method info and need not do a lookup
    // by id.

    // don't be tricked if method is called with wrong 'this'
    if(mTearOff && mTearOff->GetInterface() != iface)
        mTearOff = nsnull;

    mSet = nsnull;
    mInterface = iface;
    mMember = member;
    mMethodIndex = mMember->GetIndex() + (isSetter ? 1 : 0);
    mName = mMember->GetName();

    if(mState < HAVE_NAME)
        mState = HAVE_NAME;
#ifdef XPC_IDISPATCH_SUPPORT
    mIDispatchMember = nsnull;
#endif
}
예제 #7
0
void GdbCoreEngine::handleRoundTrip(const DebuggerResponse &response)
{
    CHECK_STATE(InferiorUnrunnable);
    Q_UNUSED(response);
    loadSymbolsForStack();
    handleStop2();
    QTimer::singleShot(1000, this, SLOT(loadAllSymbols()));
}
예제 #8
0
void GdbCoreEngine::setupInferior()
{
    CHECK_STATE(InferiorSetupRequested);
    // Do that first, otherwise no symbols are loaded.
    QFileInfo fi(m_executable);
    QByteArray path = fi.absoluteFilePath().toLocal8Bit();
    postCommand("-file-exec-and-symbols \"" + path + '"', NoFlags,
         CB(handleFileExecAndSymbols));
}
예제 #9
0
파일: nandsim.c 프로젝트: mazj/freebsd-nand
static int
nandsim_address(nand_device_t ndev, uint8_t address)
{
	if (nand_chip.inaddr == 0) {
		printf("NANDSIM: nandsim_address: "
		    "Got an address when we were not expecting it\n");
		RESET_STATE();
		return (EIO);
	}

	CLEAR_IN_STATE();

	/* The address is too long */
	if (nand_chip.address_len == 4) {
		printf("NANDSIM: nandsim_address: Address too long\n");
		RESET_STATE();
		return (EIO);
	}

	switch (nand_chip.cmd[0]) {
	case NAND_CMD_READID:
		nand_chip.incmd = 0;
		nand_chip.inaddr = 0;
		nand_chip.inread = 1;
		nand_chip.inwrite = 0;
		break;

	case NAND_CMD_READ:
		nand_chip.incmd = 0;
		nand_chip.inaddr = 1;
		nand_chip.inread = 1;
		nand_chip.inwrite = 0;
		break;

	case NAND_CMD_PROGRAM:
		/* We can enter the end command */
		nand_chip.incmd = 1;
		nand_chip.inaddr = 1;
		nand_chip.inread = 0;
		nand_chip.inwrite = 1;
		break;

	default:
		printf("NANDSIM: nandsim_address: "
		    "Invalid command when writing the address\n");
		RESET_STATE();
		return (EIO);
	}

	nand_chip.address |= address << (8 * nand_chip.address_len);
	nand_chip.address_len++;

	CHECK_STATE();

	return (0);
}
예제 #10
0
파일: main.cpp 프로젝트: Arnaud474/Warmux
bool AppWarmux::CheckInactive(SDL_Event& evnt)
{
#ifdef MAEMO
  Osso::Process();
#endif

#ifdef HAVE_HANDHELD
#  define CHECK_STATE(e) e.type==SDL_ACTIVEEVENT
#else
#  define CHECK_STATE(e) e.type==SDL_ACTIVEEVENT && e.active.state&SDL_APPACTIVE
#endif

  if (CHECK_STATE(evnt) && evnt.active.gain == 0) {
    PAUSE_LOG("Pause: entering, state=%X\n", evnt.active.state);
    JukeBox::GetInstance()->CloseDevice();
    GameTime::GetInstance()->SetWaitingForUser(true);

    Action a(Action::ACTION_ANNOUNCE_PAUSE);
    Network::GetInstance()->SendActionToAll(a);

    while (SDL_WaitEvent(&evnt)) {
#ifdef MAEMO
      Osso::Process();
#endif
      if (evnt.type == SDL_QUIT) AppWarmux::EmergencyExit();
      if (evnt.type == SDL_ACTIVEEVENT && evnt.active.gain == 1) {
        PAUSE_LOG("Active: state=%X\n", evnt.active.state);
        if ((!menu || choice != MainMenu::NONE) && GameIsRunning()) {
          PAUSE_LOG("Pause: menu=%p\n", menu);
          choice = MainMenu::NONE;
          bool exit = false;
          // There shouldn't be any other menu set, right?
          menu = new PauseMenu(exit);
          menu->Run();
          delete menu;
          menu = NULL;
          if (exit)
            Game::GetInstance()->UserAsksForEnd();
        }

        JukeBox::GetInstance()->OpenDevice();
        JukeBox::GetInstance()->NextMusic();
        GameTime::GetInstance()->SetWaitingForUser(false);

        break;
      }

      PAUSE_LOG("Dropping event %u\n", evnt.type);
    }
    return true;
  }
  return false;
}
예제 #11
0
void
XPCCallContext::SetArgsAndResultPtr(uintN argc,
                                    jsval *argv,
                                    jsval *rval)
{
    CHECK_STATE(HAVE_OBJECT);

    mArgc   = argc;
    mArgv   = argv;
    mRetVal = rval;

    mReturnValueWasSet = JS_FALSE;
    mState = HAVE_ARGS;
}
예제 #12
0
 void Joystick::Update() {
   previous_axes = axes;
   previous_buttons = buttons;
   if (glfwJoystickPresent(joystick_id)) {
     int axis_count = 0;
     const float *axis_data = glfwGetJoystickAxes(joystick_id, &axis_count);
     CHECK_STATE(axis_count);
     CHECK_STATE(axis_data);
     for (auto i = 0; i < axis_count; ++i) {
       axes[static_cast<Axis>(i)] = axis_data[i];
     }
     int button_count = 0;
     const unsigned char *button_data = glfwGetJoystickButtons(joystick_id, &button_count);
     CHECK_STATE(button_count);
     CHECK_STATE(button_data);
     for (auto i = static_cast<int>(Button::kBegin); i < static_cast<int>(Button::kEnd); ++i) {
       buttons[static_cast<Button>(i)] = button_data[i];
     }
   }
   auto now = std::chrono::high_resolution_clock::now();
   dt = std::chrono::duration_cast<std::chrono::duration<float>>(now - last_update_time).count();
   last_update_time = now;
 }
예제 #13
0
void GdbCoreEngine::handleFileExecAndSymbols(const DebuggerResponse &response)
{
    CHECK_STATE(InferiorSetupRequested);
    QString core = coreFileName();
    if (response.resultClass == ResultDone) {
        showMessage(tr("Symbols found."), StatusBar);
        handleInferiorPrepared();
    } else {
        QString msg = tr("No symbols found in core file <i>%1</i>.").arg(core)
            + _(" ") + tr("This can be caused by a path length limitation "
                          "in the core file.")
            + _(" ") + tr("Try to specify the binary using the "
                          "<i>Debug->Start Debugging->Attach to Core</i> dialog.");
        notifyInferiorSetupFailed(msg);
    }
}
예제 #14
0
void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
{
    CHECK_STATE(EngineRunRequested);
    notifyEngineRunOkAndInferiorUnrunnable();
    if (response.resultClass == ResultDone) {
        showMessage(tr("Attached to core."), StatusBar);
        // Due to the auto-solib-add off setting, we don't have any
        // symbols yet. Load them in order of importance.
        reloadStack();
        reloadModulesInternal();
        postCommand("p 5", NoFlags, CB(handleRoundTrip));
        return;
    }
    showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile)
        + QLatin1Char('\n') + QString::fromLocal8Bit(response.data["msg"].data()));
    notifyEngineIll();
}
 void TextEngineRenderer::MaybeRebuildAttenuationShader() {
   if (updater.GetCurrentState().selected_item) {
     std::set<textengine::Object *> objects, areas;
     for (auto &object : scene.objects) {
       objects.insert(object.get());
     }
     for (auto &area : scene.areas) {
       areas.insert(area.get());
     }
     const auto attenuation_shader_source = attenuation_template.AttenuationFragmentShaderSource(
         updater.GetCurrentState().selected_item, objects, areas);
     std::hash<std::string> string_hash;
     const auto source_hash = string_hash(attenuation_shader_source);
     if (source_hash != attenuation_fragment_shader_source_hash) {
       attenuation_vertex_shader.Create(GL_VERTEX_SHADER, {kAttenuationVertexShaderSource});
       
       attenuation_fragment_shader.Create(GL_FRAGMENT_SHADER, {attenuation_shader_source});
       attenuation_program.Create({&attenuation_vertex_shader, &attenuation_fragment_shader});
       attenuation_program.CompileAndLink();
       
       const auto attenuation3_shader_source = attenuation3_template.AttenuationFragmentShaderSource(
           updater.GetCurrentState().selected_item, objects, areas);
       
       attenuation3_fragment_shader.Create(GL_FRAGMENT_SHADER, {attenuation3_shader_source});
       attenuation3_program.Create({&attenuation_vertex_shader, &attenuation3_fragment_shader});
       attenuation3_program.CompileAndLink();
       
       attenuation.data.insert(attenuation.data.cend(), {
         1.0f, -1.0f,
         1.0f, 1.0f,
         -1.0f, -1.0f,
         -1.0f, 1.0f
       });
       attenuation.element_count = 4;
       attenuation.element_type = GL_TRIANGLE_STRIP;
       
       attenuation_buffer.Create(GL_ARRAY_BUFFER);
       attenuation_buffer.Data(attenuation.data_size(), attenuation.data.data(), GL_STATIC_DRAW);
       attenuation_array.Create();
       vertex_format.Apply(attenuation_array, attenuation_program);
       CHECK_STATE(!glGetError());
       attenuation_fragment_shader_source_hash = source_hash;
     }
   }
 }
예제 #16
0
void
XPCCallContext::SetName(jsval name)
{
    CHECK_STATE(HAVE_OBJECT);

    mName = name;

#ifdef XPC_IDISPATCH_SUPPORT
    mIDispatchMember = nsnull;
#endif
    if(mTearOff)
    {
        mSet = nsnull;
        mInterface = mTearOff->GetInterface();
        mMember = mInterface->FindMember(name);
        mStaticMemberIsLocal = JS_TRUE;
        if(mMember && !mMember->IsConstant())
            mMethodIndex = mMember->GetIndex();
    }
    else
    {
        mSet = mWrapper ? mWrapper->GetSet() : nsnull;

        if(mSet &&
           mSet->FindMember(name, &mMember, &mInterface,
                            mWrapper->HasProto() ?
                                mWrapper->GetProto()->GetSet() :
                                nsnull,
                            &mStaticMemberIsLocal))
        {
            if(mMember && !mMember->IsConstant())
                mMethodIndex = mMember->GetIndex();
        }
        else
        {
            mMember = nsnull;
            mInterface = nsnull;
            mStaticMemberIsLocal = JS_FALSE;
        }
    }

    mState = HAVE_NAME;
}
예제 #17
0
void GdbCoreEngine::handleTargetCore(const DebuggerResponse &response)
{
    CHECK_STATE(EngineRunRequested);
    notifyEngineRunOkAndInferiorUnrunnable();
    showMessage(tr("Attached to core."), StatusBar);
    if (response.resultClass == ResultError) {
        // We'll accept any kind of error e.g. &"Cannot access memory at address 0x2abc2a24\n"
        // Even without the stack, the user can find interesting stuff by exploring
        // the memory, globals etc.
        showStatusMessage(tr("Attach to core \"%1\" failed:").arg(runParameters().coreFile)
                          + QLatin1Char('\n') + QString::fromLocal8Bit(response.data["msg"].data())
                          + QLatin1Char('\n') + tr("Continuing nevertheless."));
    }
    // Due to the auto-solib-add off setting, we don't have any
    // symbols yet. Load them in order of importance.
    reloadStack();
    reloadModulesInternal();
    runCommand({"p 5", NoFlags, CB(handleRoundTrip)});
}
  void TextEngineRenderer::DrawRectangle(glm::vec2 center, glm::vec2 dimensions) {
    PushMatrix();
    matrix_stack.back() *= glm::scale(glm::translate(glm::mat4(1), glm::vec3(center, 0.0f)),
                                      glm::vec3(dimensions, 1));

    face_program.Use();
    face_program.Uniforms({
      {u8"projection", &projection},
      {u8"model_view", &matrix_stack.back()}
    });
    face_program.Uniforms({
      {u8"color", fill}
    });
    rectangle_array.Bind();
    glDrawArrays(unit_square.element_type, 0, unit_square.element_count);
    CHECK_STATE(!glGetError());

    PopMatrix();
  }
예제 #19
0
void
XPCCallContext::SetArgsAndResultPtr(uintN argc,
                                    jsval *argv,
                                    jsval *rval)
{
    CHECK_STATE(HAVE_OBJECT);

    if (mState < HAVE_NAME) {
        mSet = nsnull;
        mInterface = nsnull;
        mMember = nsnull;
        mStaticMemberIsLocal = false;
    }

    mArgc   = argc;
    mArgv   = argv;
    mRetVal = rval;

    mState = HAVE_ARGS;
}
예제 #20
0
void
XPCCallContext::SetIDispatchInfo(XPCNativeInterface* iface, 
                                 void * member)
{
    CHECK_STATE(HAVE_CONTEXT);

    // We are going straight to the method info and need not do a lookup
    // by id.

    // don't be tricked if method is called with wrong 'this'
    if(mTearOff && mTearOff->GetInterface() != iface)
        mTearOff = nsnull;

    mSet = nsnull;
    mInterface = iface;
    mMember = nsnull;
    mIDispatchMember = member;
    mName = reinterpret_cast<XPCDispInterface::Member*>(member)->GetName();

    if(mState < HAVE_NAME)
        mState = HAVE_NAME;
}
예제 #21
0
XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
                               JSContext* cx    /* = nsnull  */,
                               JSObject* obj    /* = nsnull  */,
                               JSObject* funobj /* = nsnull  */,
                               jsval name       /* = 0       */,
                               uintN argc       /* = NO_ARGS */,
                               jsval *argv      /* = nsnull  */,
                               jsval *rval      /* = nsnull  */)
    :   mState(INIT_FAILED),
        mXPC(nsXPConnect::GetXPConnect()),
        mThreadData(nsnull),
        mXPCContext(nsnull),
        mJSContext(cx),
        mContextPopRequired(JS_FALSE),
        mDestroyJSContextInDestructor(JS_FALSE),
        mCallerLanguage(callerLanguage),
        mCallee(nsnull)
{
    // Mark our internal string wrappers as not used. Make sure we do
    // this before any early returns, as the destructor will assert
    // based on this.
    StringWrapperEntry *se =
        reinterpret_cast<StringWrapperEntry*>(&mStringWrapperData);

    PRUint32 i;
    for(i = 0; i < XPCCCX_STRING_CACHE_SIZE; ++i)
    {
        se[i].mInUse = PR_FALSE;
    }

    if(!mXPC)
        return;

    mThreadData = XPCPerThreadData::GetData(mJSContext);

    if(!mThreadData)
        return;

    XPCJSContextStack* stack = mThreadData->GetJSContextStack();
    JSContext* topJSContext;

    if(!stack || NS_FAILED(stack->Peek(&topJSContext)))
    {
        // If we don't have a stack we're probably in shutdown.
        NS_ASSERTION(!stack, "Bad, Peek failed!");
        mJSContext = nsnull;
        return;
    }

    if(!mJSContext)
    {
        // This is slightly questionable. If called without an explicit
        // JSContext (generally a call to a wrappedJS) we will use the JSContext
        // on the top of the JSContext stack - if there is one - *before*
        // falling back on the safe JSContext.
        // This is good AND bad because it makes calls from JS -> native -> JS
        // have JS stack 'continuity' for purposes of stack traces etc.
        // Note: this *is* what the pre-XPCCallContext xpconnect did too.

        if(topJSContext)
            mJSContext = topJSContext;
        else if(NS_FAILED(stack->GetSafeJSContext(&mJSContext)) || !mJSContext)
            return;
    }

    // Get into the request as early as we can to avoid problems with scanning
    // callcontexts on other threads from within the gc callbacks.

    if(mCallerLanguage == NATIVE_CALLER)
        JS_BeginRequest(mJSContext);

    if(topJSContext != mJSContext)
    {
        if(NS_FAILED(stack->Push(mJSContext)))
        {
            NS_ERROR("bad!");
            return;
        }
        mContextPopRequired = JS_TRUE;
    }

    mXPCContext = XPCContext::GetXPCContext(mJSContext);
    mPrevCallerLanguage = mXPCContext->SetCallingLangType(mCallerLanguage);

    // hook into call context chain for our thread
    mPrevCallContext = mThreadData->SetCallContext(this);

    // We only need to addref xpconnect once so only do it if this is the first
    // context in the chain.
    if(!mPrevCallContext)
        NS_ADDREF(mXPC);

    mState = HAVE_CONTEXT;

    if(!obj)
        return;

    mMethodIndex = 0xDEAD;
    mOperandJSObject = obj;

    mState = HAVE_OBJECT;

    mTearOff = nsnull;
    mWrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(mJSContext, obj,
                                                            funobj,
                                                            &mCurrentJSObject,
                                                            &mTearOff);
    if(!mWrapper)
        return;

    DEBUG_CheckWrapperThreadSafety(mWrapper);

    mFlattenedJSObject = mWrapper->GetFlatJSObject();

    if(mTearOff)
        mScriptableInfo = nsnull;
    else
        mScriptableInfo = mWrapper->GetScriptableInfo();

    if(name)
        SetName(name);

    if(argc != NO_ARGS)
        SetArgsAndResultPtr(argc, argv, rval);

    CHECK_STATE(HAVE_OBJECT);
}
예제 #22
0
void QmlCppEngine::slaveEngineStateChanged
(DebuggerEngine *slaveEngine, const DebuggerState newState)
{
    DebuggerEngine *otherEngine = (slaveEngine == m_cppEngine)
                                  ? m_qmlEngine : m_cppEngine;

    QTC_CHECK(otherEngine != slaveEngine);

    if (debug) {
        EDEBUG("GOT SLAVE STATE: " << slaveEngine << newState);
        EDEBUG("  OTHER ENGINE: " << otherEngine << otherEngine->state());
        EDEBUG("  COMBINED ENGINE: " << this << state() << isDying());
    }

    if (state() == DebuggerFinished) {
        // We are done and don't care about slave state changes anymore.
        return;
    }

    // Idea is to follow the state of the cpp engine, except where we are stepping in QML.
    // That is, when the QmlEngine moves between InferiorStopOk, and InferiorRunOk, InferiorStopOk ...
    //
    // Accordingly, the 'active engine' is the cpp engine until the qml engine enters the
    // InferiorStopOk state. The cpp engine becomes the active one again as soon as it itself enters
    // the InferiorStopOk state.

    if (slaveEngine == m_cppEngine) {
        switch (newState) {
        case DebuggerNotReady: {
            // Can this ever happen?
            break;
        }
        case EngineSetupRequested: {
            // Set by queueSetupEngine()
            CHECK_STATE(EngineSetupRequested);
            break;
        }
        case EngineSetupFailed: {
            qmlEngine()->quitDebugger();
            notifyEngineSetupFailed();
            break;
        }
        case EngineSetupOk: {
            notifyEngineSetupOk();
            break;
        }
        case InferiorSetupRequested: {
            // Set by queueSetupInferior()
            CHECK_STATE(InferiorSetupRequested);
            break;
        }
        case InferiorSetupFailed: {
            qmlEngine()->quitDebugger();
            notifyInferiorSetupFailed();
            break;
        }
        case InferiorSetupOk: {
            notifyInferiorSetupOk();
            break;
        }
        case EngineRunRequested: {
            // set by queueRunEngine()
            break;
        }
        case EngineRunFailed: {
            qmlEngine()->quitDebugger();
            notifyEngineRunFailed();
            break;
        }
        case InferiorUnrunnable: {
            qmlEngine()->quitDebugger();
            notifyEngineRunOkAndInferiorUnrunnable();
            break;
        }
        case InferiorRunRequested: {
            // Might be set already by notifyInferiorRunRequested()
            if (state() != InferiorRunRequested) {
                CHECK_STATE(InferiorStopOk);
                notifyInferiorRunRequested();
            }
            break;
        }
        case InferiorRunOk: {
            if (state() == EngineRunRequested)
                notifyEngineRunAndInferiorRunOk();
            else if (state() == InferiorRunRequested)
                notifyInferiorRunOk();
            else
                QTC_ASSERT(false, qDebug() << state());

            if (qmlEngine()->state() == InferiorStopOk) {
                // track qml engine again
                setState(InferiorStopRequested);
                notifyInferiorStopOk();
                setActiveEngine(m_qmlEngine);
            }
            break;
        }
        case InferiorRunFailed: {
            qmlEngine()->quitDebugger();
            notifyInferiorRunFailed();
            break;
        }
        case InferiorStopRequested: {
            if (m_activeEngine == cppEngine()) {
                if (state() == InferiorRunOk) {
                    setState(InferiorStopRequested);
                } else {
                    // Might be set by doInterruptInferior()
                    CHECK_STATE(InferiorStopRequested);
                }
            } else {
                // We're debugging qml, but got an interrupt, or abort
                if (state() == InferiorRunOk) {
                    setState(InferiorStopRequested);
                } else if (state() == InferiorStopOk) {
                    notifyInferiorRunRequested();
                    notifyInferiorRunOk();
                    setState(InferiorStopRequested);
                } else if (state() == InferiorRunRequested) {
                    notifyInferiorRunOk();
                    setState(InferiorStopRequested);
                } else {
                    QTC_ASSERT(false, qDebug() << state());
                }
                // now track cpp engine
                setActiveEngine(m_cppEngine);
            }
            break;
        }
        case InferiorStopOk: {
            if (isDying()) {
                EDEBUG("... CPP ENGINE STOPPED DURING SHUTDOWN ");
                QTC_ASSERT(state() == InferiorStopRequested
                           || state() == InferiorRunOk
                           || state() == InferiorStopOk, qDebug() << state());

                // Just to make sure, we're shutting down anyway ...
                setActiveEngine(m_cppEngine);

                if (state() == InferiorStopRequested)
                    setState(InferiorStopOk);
                // otherwise we're probably inside notifyInferiorStopOk already
            } else {
                if (m_activeEngine != cppEngine()) {
                    showStatusMessage(tr("C++ debugger activated"));
                    setActiveEngine(m_cppEngine);
                }
                switch (state()) {
                case InferiorStopRequested:
                    EDEBUG("... CPP ENGINE STOPPED EXPECTEDLY");
                    notifyInferiorStopOk();
                    break;
                case EngineRunRequested:
                    EDEBUG("... CPP ENGINE STOPPED ON STARTUP");
                    notifyEngineRunAndInferiorStopOk();
                    break;
                case InferiorRunOk:
                    EDEBUG("... CPP ENGINE STOPPED SPONTANEOUSLY");
                    notifyInferiorSpontaneousStop();
                    break;
                case InferiorRunRequested:
                    // can happen if qml engine was active
                    notifyInferiorRunFailed();
                default:
                    CHECK_STATE(InferiorStopOk);
                    break;
                }
            }
            break;
        }
        case InferiorStopFailed: {
            CHECK_STATE(InferiorStopRequested);
            notifyInferiorStopFailed();
            break;
        }
        case InferiorShutdownRequested: {
            if (state() == InferiorStopOk) {
                setState(InferiorShutdownRequested);
            } else {
                // might be set by queueShutdownInferior() already
                CHECK_STATE(InferiorShutdownRequested);
            }
            qmlEngine()->quitDebugger();
            break;
        }
        case InferiorShutdownFailed: {
            CHECK_STATE(InferiorShutdownRequested);
            notifyInferiorShutdownFailed();
            break;
        }
        case InferiorShutdownOk: {
            if (state() == InferiorShutdownRequested) {
                notifyInferiorShutdownOk();
            } else {
                // we got InferiorExitOk before, but ignored it ...
                notifyInferiorExited();
            }
            break;
        }
        case EngineShutdownRequested: {
            // set by queueShutdownEngine()
            CHECK_STATE(EngineShutdownRequested);
            break;
        }
        case EngineShutdownFailed: {
            CHECK_STATE(EngineShutdownRequested);
            notifyEngineShutdownFailed();
            break;
        }
        case EngineShutdownOk: {
            CHECK_STATE(EngineShutdownRequested);
            notifyEngineShutdownOk();
            break;
        }
        case DebuggerFinished: {
            // set by queueFinishDebugger()
            CHECK_STATE(DebuggerFinished);
            break;
        }
        }
    } else {
        // QML engine state change
        if (newState == InferiorStopOk) {
            if (isDying()) {
                EDEBUG("... QML ENGINE STOPPED DURING SHUTDOWN ");

                // Just to make sure, we're shutting down anyway ...
                setActiveEngine(m_cppEngine);

                if (state() == InferiorStopRequested)
                    notifyInferiorStopOk();
                // otherwise we're probably inside notifyInferiorStopOk already
            } else {
                if (m_activeEngine != qmlEngine()) {
                    showStatusMessage(tr("QML debugger activated"));
                    setActiveEngine(m_qmlEngine);
                }

                if (state() == InferiorRunOk)
                    notifyInferiorSpontaneousStop();
                else if (state() == InferiorStopRequested)
                    notifyInferiorStopOk();
                else
                    CHECK_STATE(InferiorShutdownRequested);
            }

        } else if (newState == InferiorRunOk) {
            if (m_activeEngine == qmlEngine()) {
                CHECK_STATE(InferiorRunRequested);
                notifyInferiorRunOk();
            }
        }
    }
}
예제 #23
0
파일: nandsim.c 프로젝트: mazj/freebsd-nand
static int
nandsim_write(nand_device_t ndev, size_t len, uint8_t *data)
{
	off_t real_address;
	int i;

	CLEAR_IN_STATE();

	if (nand_chip.inwrite == 0) {
		printf("NANDSIM: nandsim_read: "
		    "Attempting to write when we can't write\n");
		RESET_STATE();
		return (EIO);
	}

	switch (nand_chip.cmd[0]) {
	case NAND_CMD_PROGRAM:
		switch(ndev->ndev_cell_size) {
		case 8:
		case 16:
			GET_OFFSET(real_address, len);
			printf("NANDSIM: nandsim_write: "
			    "Programming offset %X\n",
			    (unsigned int)real_address);

			/*
			 * The length is in terms of ndev->ndev_width bits.
			 * Adjust the length to be in terms of 8 bits.
			 */
			len = len * ndev->ndev_cell_size / 8;

			/*
			 * Iterate through each byte anding in the new
			 * data to ensure we only move from 1 -> 0
			 */
			for (i = 0; i < len; i++) {
				nand_chip.data[real_address + i] &= data[i];
			}
			RESET_STATE();
			break;
		default:
			printf("NANDSIM: nandsim_write: "
			    "Write of unknown bus width %d\n",
			    ndev->ndev_cell_size);
			RESET_STATE();
			return (EIO);
		}
		break;

	default:
		printf("NANDSIM: nandsim_write: Unknown command:");
		for (i = 0; i < nand_chip.cmd_len; i++)
			printf(" %.2X", nand_chip.cmd[i]);
		printf("\n");
		RESET_STATE();
		return (EIO);
	}

	CHECK_STATE();

	return (0);
}
예제 #24
0
파일: nandsim.c 프로젝트: mazj/freebsd-nand
static int
nandsim_read(nand_device_t ndev, size_t len, uint8_t *data)
{
	off_t real_address;
	int i;

	/*
	 * We are attempring to read the status,
	 * don't touch the state except on failure
	 */
	if (nand_chip.read_status != 0) {
		if (len != 1) {
			RESET_STATE();
			return (EIO);
		}

		nand_chip.read_status = 0;
		data[0] = NAND_STATUS_WP;
		if (nand_chip.incmd == 0 && nand_chip.inaddr == 0 &&
		    nand_chip.inread == 0 && nand_chip.inwrite == 0)
			data[0] |= NAND_STATUS_RDY | NAND_STATUS_ARDY;

		return (0);
	}

	if (nand_chip.inread == 0) {
		printf("NANDSIM: nandsim_read: "
		    "Attempting to read when we can't read\n");
		RESET_STATE();
		return (EIO);
	}

	CLEAR_IN_STATE();

	switch(nand_chip.cmd[0]) {
	case NAND_CMD_READID:
		switch(nand_chip.address) {
		case NAND_READID_MANFID:
			/* Read the Manufacturer ID */
			if (nand_chip.data_pos > 1) {
				printf("NANDSIM: nandsim_read: "
				    "Too much data have already been read\n");
				RESET_STATE();
				return (EIO);
			} else if (len > 0) {
				if (nand_chip.data_pos == 0) {
					data[0] = nand_chip.manuf;
					if (len > 1)
						data[1] = nand_chip.device;
				} else if (nand_chip.data_pos == 1)
					data[0] = nand_chip.device;

				printf("NANDSIM: nandsim_read: Read chip ID (");
				for (i = 0; i < len; i++) {
					printf("%.2X", data[i]);
					if (i != len - 1)
						printf(" ");
				}
				printf(")\n");
			} else {
				printf("NANDSIM: nandsim_read: "
				    "Read chip ID length too short\n");
				RESET_STATE();
				return (EIO);
			}
			break;

		default:
			printf("NANDSIM: nandsim_read: "
			    "Unknown or unimplemented address %X "
			    "after NAND_READID_MANFID\n", nand_chip.address);
			RESET_STATE();
			return (EIO);
		}
		RESET_STATE();
		nand_chip.inread = 1;
		break;

	case NAND_CMD_READ:
		switch(ndev->ndev_cell_size) {
		case 8:
		case 16:
			printf("NANDSIM: nandsim_read: Read page %X\n",
			    nand_chip.address);

			/* Copy the data to NAND */
			GET_OFFSET(real_address, len);
			printf("NANDSIM: nandsim_read: Reading offset %X\n",
			    (unsigned int)real_address);

			/* The length is in terms of ndev->ndi_cell_size bits */
			len = len * ndev->ndev_cell_size / 8;
			memcpy(data, &nand_chip.data[real_address], len);
			break;
		default:
			printf("NANDSIM: nandsim_read: Unknown bus width %d\n",
			    ndev->ndev_cell_size);
			RESET_STATE();
			return (EIO);
		}

		RESET_STATE();
		break;

	default:
		printf("NANDSIM: nandsim_read: Unknown command:");
		for (i = 0; i < nand_chip.cmd_len; i++)
			printf(" %.2X", nand_chip.cmd[i]);
		printf("\n");
		RESET_STATE();
		return (EIO);
	}
	nand_chip.data_pos += len;

	CHECK_STATE();

	return (0);
}
예제 #25
0
void tst_QUndoGroup::checkSignals()
{
    QUndoGroup group;
    QAction *undo_action = group.createUndoAction(0, QString("foo"));
    QAction *redo_action = group.createRedoAction(0, QString("bar"));
    QSignalSpy indexChangedSpy(&group, SIGNAL(indexChanged(int)));
    QSignalSpy cleanChangedSpy(&group, SIGNAL(cleanChanged(bool)));
    QSignalSpy canUndoChangedSpy(&group, SIGNAL(canUndoChanged(bool)));
    QSignalSpy undoTextChangedSpy(&group, SIGNAL(undoTextChanged(QString)));
    QSignalSpy canRedoChangedSpy(&group, SIGNAL(canRedoChanged(bool)));
    QSignalSpy redoTextChangedSpy(&group, SIGNAL(redoTextChanged(QString)));

    QString str;

    CHECK_STATE(0,          // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    group.undo();
    CHECK_STATE(0,     // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    group.redo();
    CHECK_STATE(0,     // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    QUndoStack *stack1 = new QUndoStack(&group);
    CHECK_STATE(0,          // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    stack1->push(new AppendCommand(&str, "foo"));
    CHECK_STATE(0,          // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    stack1->setActive();
    CHECK_STATE(stack1,     // activeStack
                false,      // clean
                true,       // canUndo
                "append",   // undoText
                false,      // canRedo
                "",         // redoText
                true,       // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    stack1->push(new InsertCommand(&str, 0, "bar"));
    CHECK_STATE(stack1,     // activeStack
                false,      // clean
                true,       // canUndo
                "insert",   // undoText
                false,      // canRedo
                "",         // redoText
                false,      // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    stack1->undo();
    CHECK_STATE(stack1,     // activeStack
                false,      // clean
                true,       // canUndo
                "append",   // undoText
                true,       // canRedo
                "insert",   // redoText
                false,      // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    stack1->undo();
    CHECK_STATE(stack1,     // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                true,       // canRedo
                "append",   // redoText
                true,       // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    stack1->undo();
    CHECK_STATE(stack1,     // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                true,       // canRedo
                "append",   // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    group.undo();
    CHECK_STATE(stack1,     // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                true,       // canRedo
                "append",   // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    group.redo();
    CHECK_STATE(stack1,     // activeStack
                false,      // clean
                true,       // canUndo
                "append",   // undoText
                true,       // canRedo
                "insert",   // redoText
                true,       // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    stack1->setActive(false);
    CHECK_STATE(0,          // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                true,       // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    QUndoStack *stack2 = new QUndoStack(&group);
    CHECK_STATE(0,          // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                false,      // cleanChanged
                false,      // indexChanged
                false,      // undoChanged
                false)      // redoChanged

    stack2->setActive();
    CHECK_STATE(stack2,     // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                true,       // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    stack1->setActive();
    CHECK_STATE(stack1,     // activeStack
                false,      // clean
                true,       // canUndo
                "append",   // undoText
                true,       // canRedo
                "insert",   // redoText
                true,       // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    delete stack1;
    CHECK_STATE(0,          // activeStack
                true,       // clean
                false,      // canUndo
                "",         // undoText
                false,      // canRedo
                "",         // redoText
                true,       // cleanChanged
                true,       // indexChanged
                true,       // undoChanged
                true)       // redoChanged

    delete undo_action;
    delete redo_action;
}
예제 #26
0
파일: nandsim.c 프로젝트: mazj/freebsd-nand
/* TODO: Set the in* state correctly before returning from the functions */
static int
nandsim_command(nand_device_t ndev, uint8_t cmd)
{
	/* Some commands may be sent with the LUN in any state */
	switch(cmd) {
	case NAND_CMD_RESET:
		printf("NANDSIM: nandsim_command: Reset chip\n");
		RESET_STATE();
		return (0);

	case NAND_CMD_READ_STATUS:
		printf("NANDSIM: nandsim_command: Called read_status\n");
		nand_chip.read_status = 1;
		return (0);

	default:
		break;
	}

	if (nand_chip.startcmd != 0) {
		/*
		 * New command, we have already called RESET_STATE()
		 * as that is the only way to get here
		 */
		nand_chip.startcmd = 0;
		nand_chip.incmd = 1;
	}

	/* Check if we are not able to handle a command */
	if (nand_chip.incmd == 0) {
		printf("NANDSIM: nandsim_command: "
		    "Got a command when we were not expecting it: 0x%X\n", cmd);
		RESET_STATE();
		return (EIO);
	}

	/* Store the commnad */
	switch(nand_chip.cmd_len) {
	case 0:
	case 1:
		nand_chip.cmd[nand_chip.cmd_len] = cmd;
		nand_chip.cmd_len++;
		break;
	default:
		printf("NANDSIM: nandsim_command: "
		    "Attempting to write too many commands\n");
		RESET_STATE();
		return (EIO);
	}

	CLEAR_IN_STATE();

	/* Which command are we in */
	switch (nand_chip.cmd[0]) {
	case NAND_CMD_PROGRAM:
		switch (nand_chip.cmd_len) {
		case 1:
			/* We can send the address now */
			nand_chip.incmd = 0;
			nand_chip.inaddr = 1;
			nand_chip.inread = 0;
			nand_chip.inwrite = 0;
			break;
		case 2:
			/* We have finished the program sysle */
			RESET_STATE();
			if (nand_chip.cmd[1] != NAND_CMD_PROGRAM_END) {
				printf("NANDSIM: nandsim_command: "
				    "Unknown command after NAND_CMD_PROGRAM\n");
				return (EIO);
			}
			break;
		}
		break;

	case NAND_CMD_READ:
		switch (nand_chip.cmd_len) {
		case 1:
			/* We can send the address now */
			nand_chip.incmd = 0;
			nand_chip.inaddr = 1;
			nand_chip.inread = 0;
			nand_chip.inwrite = 0;
			break;
		case 2:
			if (nand_chip.cmd[1] != NAND_CMD_READ_START) {
				printf("NANDSIM: nandsim_command: "
				    "Unknown command after NAND_CMD_READ\n");
				RESET_STATE();
				return (EIO);
			}
			if (!nand_chip.read_start) {
				printf("NANDSIM: nandsim_command: "
				    "Received NAND_CMD_READ_START when we "
				    "didn't expect it\n");
				RESET_STATE();
				return (EIO);
			}
			nand_chip.incmd = 0;
			nand_chip.inaddr = 0;
			nand_chip.inread = 1;
			nand_chip.inwrite = 0;
			break;
		}
		break;

	case NAND_CMD_ERASE:
		switch (nand_chip.cmd_len) {
		case 1:
			/* We can send the address now */
			nand_chip.incmd = 0;
			nand_chip.inaddr = 1;
			nand_chip.inread = 0;
			nand_chip.inwrite = 0;
			break;
		case 2:
			RESET_STATE();
			if (nand_chip.cmd[1] != NAND_CMD_ERASE_END) {
				printf("NANDSIM: nandsim_command: "
				    "Unknown command after NAND_CMD_ERASE\n");
				return (EIO);
			}
			break;
		}
		break;

	case NAND_CMD_READID:
		/* If we are reading the manifest ID we can move to read */
		if (nand_chip.cmd_len > 1) {
			printf("NANDSIM: nandsim_command: "
			    "NAND_CMD_READID only supports 1 command\n");
			RESET_STATE();
			return (EIO);
		}
		nand_chip.incmd = 0;
		nand_chip.inaddr = 1;
		nand_chip.inread = 0;
		nand_chip.inwrite = 0;
		break;

	default:
		printf("NANDSIM: nandsim_command: "
		    "Unknown or unimplemented command\n");
		RESET_STATE();
		return (EIO);
	}

	CHECK_STATE();

	return (0);
}
예제 #27
0
void
XPCCallContext::Init(XPCContext::LangType callerLanguage,
                     JSBool callBeginRequest,
                     JSObject* obj,
                     JSObject* funobj,
                     WrapperInitOptions wrapperInitOptions,
                     jsid name,
                     uintN argc,
                     jsval *argv,
                     jsval *rval)
{
    if (!mXPC)
        return;

    mThreadData = XPCPerThreadData::GetData(mJSContext);

    if (!mThreadData)
        return;

    XPCJSContextStack* stack = mThreadData->GetJSContextStack();
    JSContext* topJSContext;

    if (!stack || NS_FAILED(stack->Peek(&topJSContext))) {
        // If we don't have a stack we're probably in shutdown.
        NS_ASSERTION(!stack, "Bad, Peek failed!");
        mJSContext = nsnull;
        return;
    }

    if (!mJSContext) {
        // This is slightly questionable. If called without an explicit
        // JSContext (generally a call to a wrappedJS) we will use the JSContext
        // on the top of the JSContext stack - if there is one - *before*
        // falling back on the safe JSContext.
        // This is good AND bad because it makes calls from JS -> native -> JS
        // have JS stack 'continuity' for purposes of stack traces etc.
        // Note: this *is* what the pre-XPCCallContext xpconnect did too.

        if (topJSContext)
            mJSContext = topJSContext;
        else if (NS_FAILED(stack->GetSafeJSContext(&mJSContext)) || !mJSContext)
            return;
    }

    if (topJSContext != mJSContext) {
        if (NS_FAILED(stack->Push(mJSContext))) {
            NS_ERROR("bad!");
            return;
        }
        mContextPopRequired = true;
    }

    // Get into the request as early as we can to avoid problems with scanning
    // callcontexts on other threads from within the gc callbacks.

    NS_ASSERTION(!callBeginRequest || mCallerLanguage == NATIVE_CALLER,
                 "Don't call JS_BeginRequest unless the caller is native.");
    if (callBeginRequest)
        JS_BeginRequest(mJSContext);

    mXPCContext = XPCContext::GetXPCContext(mJSContext);
    mPrevCallerLanguage = mXPCContext->SetCallingLangType(mCallerLanguage);

    // hook into call context chain for our thread
    mPrevCallContext = mThreadData->SetCallContext(this);

    // We only need to addref xpconnect once so only do it if this is the first
    // context in the chain.
    if (!mPrevCallContext)
        NS_ADDREF(mXPC);

    mState = HAVE_CONTEXT;

    if (!obj)
        return;

    mScopeForNewJSObjects = obj;

    mState = HAVE_SCOPE;

    mMethodIndex = 0xDEAD;

    mState = HAVE_OBJECT;

    mTearOff = nsnull;
    if (wrapperInitOptions == INIT_SHOULD_LOOKUP_WRAPPER) {
        mWrapper = XPCWrappedNative::GetWrappedNativeOfJSObject(mJSContext, obj,
                                                                funobj,
                                                                &mFlattenedJSObject,
                                                                &mTearOff);
        if (mWrapper) {
            DEBUG_CheckWrapperThreadSafety(mWrapper);

            mFlattenedJSObject = mWrapper->GetFlatJSObject();

            if (mTearOff)
                mScriptableInfo = nsnull;
            else
                mScriptableInfo = mWrapper->GetScriptableInfo();
        } else {
            NS_ABORT_IF_FALSE(!mFlattenedJSObject || IS_SLIM_WRAPPER(mFlattenedJSObject),
                              "should have a slim wrapper");
        }
    }

    if (!JSID_IS_VOID(name))
        SetName(name);

    if (argc != NO_ARGS)
        SetArgsAndResultPtr(argc, argv, rval);

    CHECK_STATE(HAVE_OBJECT);
}
  void TextEngineRenderer::Render() {
    GameState &current_state = updater.GetCurrentState();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    PushMatrix();
    matrix_stack.back() *= glm::scale(glm::mat4(1), glm::vec3(glm::vec2(current_state.zoom * 0.1f), 1.0f));
    matrix_stack.back() *= glm::translate(glm::mat4(1), glm::vec3(-current_state.camera_position, 0));

    const glm::vec2 position = glm::vec2(current_state.player_body->GetPosition().x,
                                         current_state.player_body->GetPosition().y);

    fill = glm::vec4(0.0f, 0.5f, 0.3f, 0.5f);
    for (const auto &area : scene.areas) {
      if (area->invisible) {
        continue;
      }
      if (Shape::kAxisAlignedBoundingBox == area->shape) {
        DrawAxisAlignedBoundingBox(area->aabb);
      } else {
        DrawCircle(area->aabb.center(), area->aabb.radius());
      }
    }
    fill = glm::vec4(1.0f, 0.0f, 0.0f, 0.5f);
    for (const auto &object : scene.objects) {
      if (object->invisible) {
        continue;
      }
      if (Shape::kAxisAlignedBoundingBox == object->shape) {
        DrawAxisAlignedBoundingBox(object->aabb);
      } else {
        DrawCircle(object->aabb.center(), object->aabb.radius());
      }	
    }

    const glm::mat4 normalized_to_reversed = glm::scale(glm::mat4(), glm::vec3(1.0f, -1.0f, 1.0f));
    const glm::mat4 reversed_to_offset = glm::translate(glm::mat4(), glm::vec3(glm::vec2(1.0f), 0.0f));
    const glm::mat4 offset_to_screen = glm::scale(glm::mat4(), glm::vec3(glm::vec2(0.5f), 1.0f));
    const glm::mat4 screen_to_window = glm::scale(glm::mat4(), glm::vec3(width, height, 1.0f));

    const glm::mat4 transform = (screen_to_window * offset_to_screen *
                                 reversed_to_offset * normalized_to_reversed *
                                 model_view * projection * matrix_stack.back());
    const glm::mat4 transform2 = (screen_to_window * offset_to_screen *
                                  reversed_to_offset *
                                  model_view * projection * matrix_stack.back());
    const auto inverse = glm::inverse(transform2);
    const glm::vec4 homogeneous = transform * glm::vec4(position, 0.0f, 1.0f);
    const glm::vec2 transformed = homogeneous.xy() / homogeneous.w;

    fill = glm::vec4(0.5f, 0.5f, 0.6f, 1.0f);
    PushMatrix();
    matrix_stack.back() *= glm::translate(glm::mat4(1), glm::vec3(position, 0));
    matrix_stack.back() *= glm::rotate(glm::mat4(1),
                                       current_state.player_body->GetAngle(),
                                       glm::vec3(0, 0, 1));
    DrawRectangle(glm::vec2(0), glm::vec2(0.25f, 0.5f));
    PopMatrix();
    PopMatrix();
    
    if (edit) {
      MaybeRebuildAttenuationShader();
      if (current_state.selected_item) {
        attenuation3_program.Use();
        attenuation3_program.Uniforms({
          {u8"model_view_inverse", &inverse}
        });
        const auto isaabb3 = Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape;
        glUniform1i(attenuation3_program.GetUniformLocation(u8"selected_isaabb"), isaabb3);
        if (Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape) {
          attenuation3_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.minimum},
            {u8"selected_maximum_or_radius", current_state.selected_item->aabb.maximum},
          });
          CHECK_STATE(!glGetError());
        } else {
          attenuation3_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.center()},
            {u8"selected_maximum_or_radius", glm::vec2(current_state.selected_item->aabb.radius())},
          });
          CHECK_STATE(!glGetError());
        }
        const auto attenuation3_coefficients = glm::vec3(
            current_state.selected_item->base_attenuation,
                current_state.selected_item->linear_attenuation,
                    current_state.selected_item->quadratic_attenuation);
        attenuation3_program.Uniforms({
          {u8"selected_attenuation", attenuation3_coefficients},
        });
        const auto color3 = glm::vec4(0, 0, 0, 0.125);
        attenuation3_program.Uniforms({
          {u8"color", color3}
        });
        attenuation_array.Bind();
        glDrawArrays(attenuation.element_type, 0, attenuation.element_count);
        CHECK_STATE(!glGetError());
        
        attenuation_program.Use();
        attenuation_program.Uniforms({
          {u8"model_view_inverse", &inverse}
        });
        const auto isaabb = Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape;
        glUniform1i(attenuation_program.GetUniformLocation(u8"selected_isaabb"), isaabb);
        if (Shape::kAxisAlignedBoundingBox == current_state.selected_item->shape) {
          attenuation_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.minimum},
            {u8"selected_maximum_or_radius", current_state.selected_item->aabb.maximum},
          });
          CHECK_STATE(!glGetError());
        } else {
          attenuation_program.Uniforms({
            {u8"selected_minimum_or_center", current_state.selected_item->aabb.center()},
            {u8"selected_maximum_or_radius", glm::vec2(current_state.selected_item->aabb.radius())},
          });
          CHECK_STATE(!glGetError());
        }
        const auto attenuation_coefficients = glm::vec3(
            current_state.selected_item->base_attenuation,
                current_state.selected_item->linear_attenuation,
                    current_state.selected_item->quadratic_attenuation);
        attenuation_program.Uniforms({
          {u8"selected_attenuation", attenuation_coefficients},
        });
        const auto color = glm::vec4(0, 0, 0, 0.5);
        attenuation_program.Uniforms({
          {u8"color", color}
        });
        attenuation_array.Bind();
        glDrawArrays(attenuation.element_type, 0, attenuation.element_count);
        CHECK_STATE(!glGetError());
      }
    }

    const auto mouse_position = 2.0f * mouse.get_cursor_position();
    unsigned char mouse_buttons = 0;
    if (mouse.IsButtonDown(GLFW_MOUSE_BUTTON_1)) {
      mouse_buttons |= IMGUI_MBUT_LEFT;
    }
    if (mouse.IsButtonDown(GLFW_MOUSE_BUTTON_2)) {
      mouse_buttons |= IMGUI_MBUT_RIGHT;
    }
    
    if (edit) {
      imguiBeginFrame(mouse_position.x, height - mouse_position.y, mouse_buttons, 0);
      
      for (auto &area : scene.areas) {
        const glm::vec4 homogeneous = transform * glm::vec4(area->aabb.minimum.x, area->aabb.maximum.y, 0.0f, 1.0f);
        const glm::vec2 transformed = homogeneous.xy() / homogeneous.w;
        imguiDrawText(transformed.x, height - transformed.y, IMGUI_ALIGN_LEFT, area->name.c_str(), imguiRGBA(0, 0, 0));
      }
      
      for (auto &object : scene.objects) {
        const glm::vec4 homogeneous = transform * glm::vec4(object->aabb.minimum.x, object->aabb.maximum.y, 0.0f, 1.0f);
        const glm::vec2 transformed = homogeneous.xy() / homogeneous.w;
        imguiDrawText(transformed.x, height - transformed.y, IMGUI_ALIGN_LEFT, object->name.c_str(), imguiRGBA(0, 0, 0));
      }
      
      if (current_state.selected_item) {
        std::ostringstream name, constant, linear, quadratic;
        name << current_state.selected_item->name;
        imguiDrawText(10, height - 50, IMGUI_ALIGN_LEFT, name.str().c_str(), imguiRGBA(0, 0, 0));
        constant << "c: " << current_state.selected_item->base_attenuation;
        imguiDrawText(10, height - 75, IMGUI_ALIGN_LEFT, constant.str().c_str(), imguiRGBA(0, 0, 0));
        linear << "l: " << current_state.selected_item->linear_attenuation;
        imguiDrawText(10, height - 100, IMGUI_ALIGN_LEFT, linear.str().c_str(), imguiRGBA(0, 0, 0));
        quadratic << "q: " << current_state.selected_item->quadratic_attenuation << std::endl;
        imguiDrawText(10, height - 125, IMGUI_ALIGN_LEFT, quadratic.str().c_str(), imguiRGBA(0, 0, 0));
      }
      
      imguiEndFrame();
    }

    imguiRenderGLDraw(width, height);
  }