void X86AsmGenerator::storeArrayIemHandler(){
	int backTimes = -1;
	SymbolTableItem *storeArray = curSymbolTable->getItem(curMidCode.arg1, 0, backTimes);
	int itemSize = 0;
	if (storeArray->symbolType == arrayInteger) {
		itemSize = INTEGER_SIZE;
	}else if (storeArray->symbolType == arrayChar) {
		itemSize = CHAR_SIZE;
	}else {
		errorGlobal(WAIT_FOR_DEFINE);
	}

	if (backTimes == 0) {
		genX86Asm("pop eax");	//val
		genX86Asm("pop ecx");	//offset
		genX86Asm("mov ebx, ebp");
		genX86Asm("sub ebx, " + intToString(storeArray->addr));

		genX86Asm("imul ecx, ecx, " + intToString(itemSize));	//offset*itemsize
		genX86Asm("sub ebx, ecx");
		genX86Asm("mov DWORD ptr [ebx], eax");
	} else if (backTimes > 0) {
		setDynamicBaseAddrReg(backTimes);
		genX86Asm("pop eax");	//val
		genX86Asm("pop ecx");	//offset
		genX86Asm("sub ebx, " + intToString(storeArray->addr));

		genX86Asm("imul ecx, ecx, " + intToString(itemSize));	//offset*itemsize
		genX86Asm("sub ebx, ecx");
		genX86Asm("mov DWORD ptr [ebx], eax");
	} else {
		errorGlobal(WAIT_FOR_DEFINE);
	}
}
Exemple #2
0
void
AutoJSAPI::ReportException()
{
  MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
  if (!HasException()) {
    return;
  }

  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
  // compartment when the destructor is called. However, the JS engine
  // requires us to be in a compartment when we fetch the pending exception.
  // In this case, we enter the privileged junk scope and don't dispatch any
  // error events.
  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
  if (!errorGlobal)
    errorGlobal = xpc::PrivilegedJunkScope();
  JSAutoCompartment ac(cx(), errorGlobal);
  nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
  JS::Rooted<JS::Value> exn(cx());
  js::ErrorReport jsReport(cx());
  if (StealException(&exn) && jsReport.init(cx(), exn)) {
    nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
    xpcReport->Init(jsReport.report(), jsReport.message(),
                    nsContentUtils::IsCallerChrome(),
                    win ? win->WindowID() : 0);
    if (win) {
      DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
    } else {
      xpcReport->LogToConsole();
    }
  } else {
    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
  }
}
void
AutoJSAPI::ReportException()
{
  MOZ_ASSERT(OwnsErrorReporting(), "This is not our exception to report!");
  if (!HasException()) {
    return;
  }

  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
  // compartment when the destructor is called. However, the JS engine
  // requires us to be in a compartment when we fetch the pending exception.
  // In this case, we enter the privileged junk scope and don't dispatch any
  // error events.
  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
  if (!errorGlobal) {
    if (mIsMainThread) {
      errorGlobal = xpc::PrivilegedJunkScope();
    } else {
      errorGlobal = workers::GetCurrentThreadWorkerGlobal();
    }
  }
  JSAutoCompartment ac(cx(), errorGlobal);
  JS::Rooted<JS::Value> exn(cx());
  js::ErrorReport jsReport(cx());
  if (StealException(&exn) && jsReport.init(cx(), exn)) {
    if (mIsMainThread) {
      RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
      RefPtr<nsGlobalWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
      nsPIDOMWindowInner* inner = win ? win->AsInner() : nullptr;
      xpcReport->Init(jsReport.report(), jsReport.message(),
                      nsContentUtils::IsCallerChrome(),
                      inner ? inner->WindowID() : 0);
      if (inner) {
        DispatchScriptErrorEvent(inner, JS_GetRuntime(cx()), xpcReport, exn);
      } else {
        xpcReport->LogToConsole();
      }
    } else {
      // On a worker, we just use the worker error reporting mechanism and don't
      // bother with xpc::ErrorReport.  This will ensure that all the right
      // events (which are a lot more complicated than in the window case) get
      // fired.
      workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
      MOZ_ASSERT(worker);
      MOZ_ASSERT(worker->GetJSContext() == cx());
      // Before invoking ReportError, put the exception back on the context,
      // because it may want to put it in its error events and has no other way
      // to get hold of it.  After we invoke ReportError, clear the exception on
      // cx(), just in case ReportError didn't.
      JS_SetPendingException(cx(), exn);
      worker->ReportError(cx(), jsReport.message(), jsReport.report());
      ClearException();
    }
  } else {
    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
    ClearException();
  }
}
AutoJSAPI::~AutoJSAPI()
{
  if (mOwnErrorReporting) {
    MOZ_ASSERT(NS_IsMainThread(), "See corresponding assertion in TakeOwnershipOfErrorReporting()");
    JS::ContextOptionsRef(cx()).setDontReportUncaught(mOldDontReportUncaught);

    if (HasException()) {

      // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
      // compartment when the destructor is called. However, the JS engine
      // requires us to be in a compartment when we fetch the pending exception.
      // In this case, we enter the privileged junk scope and don't dispatch any
      // error events.
      JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
      if (!errorGlobal)
        errorGlobal = xpc::PrivilegedJunkScope();
      JSAutoCompartment ac(cx(), errorGlobal);
      nsCOMPtr<nsPIDOMWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
      const char *category = nsContentUtils::IsCallerChrome() ? "chrome javascript"
                                                              : "content javascript";
      JS::Rooted<JS::Value> exn(cx());
      js::ErrorReport jsReport(cx());
      if (StealException(&exn) && jsReport.init(cx(), exn)) {
        nsRefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
        xpcReport->Init(jsReport.report(), jsReport.message(), category,
                        win ? win->WindowID() : 0);
        if (win) {
          DispatchScriptErrorEvent(win, JS_GetRuntime(cx()), xpcReport, exn);
        } else {
          xpcReport->LogToConsole();
        }
      } else {
        NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
      }
    }
  }

  if (mOldErrorReporter.isSome()) {
    JS_SetErrorReporter(JS_GetRuntime(cx()), mOldErrorReporter.value());
  }
}
void
AutoJSAPI::ReportException()
{
  if (!HasException()) {
    return;
  }

  // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
  // compartment when the destructor is called. However, the JS engine
  // requires us to be in a compartment when we fetch the pending exception.
  // In this case, we enter the privileged junk scope and don't dispatch any
  // error events.
  JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
  if (!errorGlobal) {
    if (mIsMainThread) {
      errorGlobal = xpc::PrivilegedJunkScope();
    } else {
      errorGlobal = workers::GetCurrentThreadWorkerGlobal();
    }
  }
  JSAutoCompartment ac(cx(), errorGlobal);
  JS::Rooted<JS::Value> exn(cx());
  js::ErrorReport jsReport(cx());
  if (StealException(&exn) &&
      jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects)) {
    if (mIsMainThread) {
      RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();

      RefPtr<nsGlobalWindow> win = xpc::WindowGlobalOrNull(errorGlobal);
      if (!win) {
        // We run addons in a separate privileged compartment, but they still
        // expect to trigger the onerror handler of their associated DOM Window.
        win = xpc::AddonWindowOrNull(errorGlobal);
      }
      nsPIDOMWindowInner* inner = win ? win->AsInner() : nullptr;
      xpcReport->Init(jsReport.report(), jsReport.toStringResult().c_str(),
                      nsContentUtils::IsCallerChrome(),
                      inner ? inner->WindowID() : 0);
      if (inner && jsReport.report()->errorNumber != JSMSG_OUT_OF_MEMORY) {
        JS::RootingContext* rcx = JS::RootingContext::get(cx());
        DispatchScriptErrorEvent(inner, rcx, xpcReport, exn);
      } else {
        JS::Rooted<JSObject*> stack(cx(),
          xpc::FindExceptionStackForConsoleReport(inner, exn));
        xpcReport->LogToConsoleWithStack(stack);
      }
    } else {
      // On a worker, we just use the worker error reporting mechanism and don't
      // bother with xpc::ErrorReport.  This will ensure that all the right
      // events (which are a lot more complicated than in the window case) get
      // fired.
      workers::WorkerPrivate* worker = workers::GetCurrentThreadWorkerPrivate();
      MOZ_ASSERT(worker);
      MOZ_ASSERT(worker->GetJSContext() == cx());
      // Before invoking ReportError, put the exception back on the context,
      // because it may want to put it in its error events and has no other way
      // to get hold of it.  After we invoke ReportError, clear the exception on
      // cx(), just in case ReportError didn't.
      JS_SetPendingException(cx(), exn);
      worker->ReportError(cx(), jsReport.toStringResult(), jsReport.report());
      ClearException();
    }
  } else {
    NS_WARNING("OOMed while acquiring uncaught exception from JSAPI");
    ClearException();
  }
}
void X86AsmGenerator::pushRefHandler(){
	//push var reference
	int backTimes = -1;
	SymbolTableItem *pushedVar = curSymbolTable->getItem(curMidCode.arg1, 0, backTimes);
	int relativeAddr = -pushedVar->addr;
	string rAddr = relativeAddr >= 0 ? "+" + intToString(relativeAddr) : intToString(relativeAddr);
	if (pushedVar->isRef) {
		if (backTimes == 0) {
			genX86Asm("push DWORD ptr [ebp" + rAddr + "]");
		} else if (backTimes > 0) {
			setDynamicBaseAddrReg(backTimes);
			genX86Asm("push DWORD ptr [ebx" + rAddr + "]");
		} else {
			//小于零错误,该错误应该在语义分析阶段就已经进行了处理.
		}
	} else {
		if (pushedVar->symbolType == integersym || pushedVar->symbolType == charsym) {
			if (backTimes == 0) {
				genX86Asm("lea eax, [ebp" + rAddr + "]");
				genX86Asm("push eax");
			} else if (backTimes > 0) {
				setDynamicBaseAddrReg(backTimes);
				genX86Asm("lea eax, [ebx" + rAddr + "]");
				genX86Asm("push eax");
			} else {

			}
		}else if (pushedVar->symbolType == arrayInteger || pushedVar->symbolType == arrayChar) {
			backTimes = -1;
			SymbolTableItem *arr = curSymbolTable->getItem(curMidCode.arg1, 0, backTimes);
			int itemSize = 0;
			if (arr->symbolType == arrayInteger) {
				itemSize = INTEGER_SIZE;
			}else if (arr->symbolType == arrayChar) {
				itemSize = CHAR_SIZE;
			}else {
				errorGlobal(WAIT_FOR_DEFINE);
			}

			if (backTimes == 0) {
				genX86Asm("pop ecx");	//offset

				genX86Asm("imul ecx, ecx, " + intToString(itemSize));	//offset*itemsize
				genX86Asm("mov ebx, ebp");
				genX86Asm("sub ebx, " + intToString(arr->addr));
				genX86Asm("sub ebx, ecx");
				genX86Asm("push ebx");
			} else if (backTimes > 0) {
				setDynamicBaseAddrReg(backTimes);
				genX86Asm("pop ecx");	//offset

				genX86Asm("imul ecx, ecx, " + intToString(itemSize));	//offset*itemsize
				genX86Asm("sub ebx, " + intToString(arr->addr));
				genX86Asm("sub ebx, ecx");
				genX86Asm("push ebx");
			} else {

			}
		}
	}
}