Esempio n. 1
0
void
AutoEntryScript::DocshellEntryMonitor::Entry(JSContext* aCx, JSFunction* aFunction,
                                             JSScript* aScript, JS::Handle<JS::Value> aAsyncStack,
                                             JS::Handle<JSString*> aAsyncCause)
{
  JS::Rooted<JSFunction*> rootedFunction(aCx);
  if (aFunction) {
    rootedFunction = aFunction;
  }
  JS::Rooted<JSScript*> rootedScript(aCx);
  if (aScript) {
    rootedScript = aScript;
  }

  nsCOMPtr<nsPIDOMWindowInner> window =
    do_QueryInterface(xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx)));
  if (!window || !window->GetDocShell() ||
      !window->GetDocShell()->GetRecordProfileTimelineMarkers()) {
    return;
  }

  nsCOMPtr<nsIDocShell> docShellForJSRunToCompletion = window->GetDocShell();
  nsString filename;
  uint32_t lineNumber = 0;

  js::AutoStableStringChars functionName(aCx);
  if (rootedFunction) {
    JS::Rooted<JSString*> displayId(aCx, JS_GetFunctionDisplayId(rootedFunction));
    if (displayId) {
      if (!functionName.initTwoByte(aCx, displayId)) {
        JS_ClearPendingException(aCx);
        return;
      }
    }
  }

  if (!rootedScript) {
    rootedScript = JS_GetFunctionScript(aCx, rootedFunction);
  }
  if (rootedScript) {
    filename = NS_ConvertUTF8toUTF16(JS_GetScriptFilename(rootedScript));
    lineNumber = JS_GetScriptBaseLineNumber(aCx, rootedScript);
  }

  if (!filename.IsEmpty() || functionName.isTwoByte()) {
    const char16_t* functionNameChars = functionName.isTwoByte() ?
      functionName.twoByteChars() : nullptr;

    JS::Rooted<JS::Value> asyncCauseValue(aCx, aAsyncCause ? StringValue(aAsyncCause) :
                                          JS::NullValue());
    docShellForJSRunToCompletion->NotifyJSRunToCompletionStart(mReason,
                                                               functionNameChars,
                                                               filename.BeginReading(),
                                                               lineNumber, aAsyncStack,
                                                               asyncCauseValue);
  }
}
Esempio n. 2
0
nsresult
XPCJSStackFrame::CreateStack(JSContext* cx, XPCJSStackFrame** stack)
{
    static const unsigned MAX_FRAMES = 100;

    nsRefPtr<XPCJSStackFrame> first = new XPCJSStackFrame();
    nsRefPtr<XPCJSStackFrame> self = first;

    JS::StackDescription* desc = JS::DescribeStack(cx, MAX_FRAMES);
    if (!desc)
        return NS_ERROR_FAILURE;

    for (size_t i = 0; i < desc->nframes && self; i++) {
        self->mLanguage = nsIProgrammingLanguage::JAVASCRIPT;

	JSAutoCompartment ac(cx, desc->frames[i].script);
        const char* filename = JS_GetScriptFilename(cx, desc->frames[i].script);
        if (filename) {
            self->mFilename = (char*)
                nsMemory::Clone(filename,
                                sizeof(char)*(strlen(filename)+1));
        }

        self->mLineno = desc->frames[i].lineno;

        JSFunction* fun = desc->frames[i].fun;
        if (fun) {
            JS::RootedString funid(cx, JS_GetFunctionDisplayId(fun));
            if (funid) {
                size_t length = JS_GetStringEncodingLength(cx, funid);
                if (length != size_t(-1)) {
                    self->mFunname = static_cast<char *>(nsMemory::Alloc(length + 1));
                    if (self->mFunname) {
                        JS_EncodeStringToBuffer(cx, funid, self->mFunname, length);
                        self->mFunname[length] = '\0';
                    }
                }
            }
        }

        XPCJSStackFrame* frame = new XPCJSStackFrame();
        self->mCaller = frame;
        self = frame;
    }

    JS::FreeStackDescription(cx, desc);

    *stack = first.forget().get();
    return NS_OK;
}
Esempio n. 3
0
std::string
gjs_debug_value(JS::Value v)
{
    std::ostringstream out;
    if (v.isNull())
        return "null";
    if (v.isUndefined())
        return "undefined";
    if (v.isInt32()) {
        out << v.toInt32();
        return out.str();
    }
    if (v.isDouble()) {
        out << v.toDouble();
        return out.str();
    }
    if (v.isString()) {
        out << gjs_debug_string(v.toString());
        return out.str();
    }
    if (v.isSymbol()) {
        out << gjs_debug_symbol(v.toSymbol());
        return out.str();
    }
    if (v.isObject() && js::IsFunctionObject(&v.toObject())) {
        JSFunction* fun = JS_GetObjectFunction(&v.toObject());
        JSString *display_name = JS_GetFunctionDisplayId(fun);
        if (display_name)
            out << "<function " << gjs_debug_string(display_name);
        else
            out << "<unnamed function";
        out << " at " << fun << '>';
        return out.str();
    }
    if (v.isObject()) {
        out << gjs_debug_object(&v.toObject());
        return out.str();
    }
    if (v.isBoolean())
        return (v.toBoolean() ? "true" : "false");
    if (v.isMagic())
        return "<magic>";
    return "unexpected value";
}