+
+JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return 0;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+
+ String name = exec->vmEntryGlobalObject()->name();
+ if (name.isNull())
+ return 0;
+
+ return OpaqueJSString::create(name).leakRef();
+}
+
+void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name)
+{
+ if (!ctx) {
+ ASSERT_NOT_REACHED();
+ return;
+ }
+
+ ExecState* exec = toJS(ctx);
+ JSLockHolder locker(exec);
+
+ exec->vmEntryGlobalObject()->setName(name ? name->string() : String());
+}
+
+
+class BacktraceFunctor {
+public:
+ BacktraceFunctor(StringBuilder& builder, unsigned remainingCapacityForFrameCapture)
+ : m_builder(builder)
+ , m_remainingCapacityForFrameCapture(remainingCapacityForFrameCapture)
+ {
+ }
+
+ StackVisitor::Status operator()(StackVisitor& visitor)
+ {
+ if (m_remainingCapacityForFrameCapture) {
+ // If callee is unknown, but we've not added any frame yet, we should
+ // still add the frame, because something called us, and gave us arguments.
+ JSObject* callee = visitor->callee();
+ if (!callee && visitor->index())
+ return StackVisitor::Done;
+
+ StringBuilder& builder = m_builder;
+ if (!builder.isEmpty())
+ builder.append('\n');
+ builder.append('#');
+ builder.appendNumber(visitor->index());
+ builder.append(' ');
+ builder.append(visitor->functionName());
+ builder.appendLiteral("() at ");
+ builder.append(visitor->sourceURL());
+ if (visitor->isJSFrame()) {
+ builder.append(':');
+ unsigned lineNumber;
+ unsigned unusedColumn;
+ visitor->computeLineAndColumn(lineNumber, unusedColumn);
+ builder.appendNumber(lineNumber);
+ }
+
+ if (!callee)
+ return StackVisitor::Done;
+
+ m_remainingCapacityForFrameCapture--;
+ return StackVisitor::Continue;
+ }
+ return StackVisitor::Done;
+ }
+
+private:
+ StringBuilder& m_builder;
+ unsigned m_remainingCapacityForFrameCapture;
+};
+