summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/interpreter/VMInspector.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/interpreter/VMInspector.cpp
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/JavaScriptCore/interpreter/VMInspector.cpp')
-rw-r--r--Source/JavaScriptCore/interpreter/VMInspector.cpp572
1 files changed, 0 insertions, 572 deletions
diff --git a/Source/JavaScriptCore/interpreter/VMInspector.cpp b/Source/JavaScriptCore/interpreter/VMInspector.cpp
deleted file mode 100644
index fbb49413d..000000000
--- a/Source/JavaScriptCore/interpreter/VMInspector.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "VMInspector.h"
-
-#if ENABLE(VMINSPECTOR)
-
-#include <wtf/ASCIICType.h>
-#include <wtf/text/WTFString.h>
-
-namespace JSC {
-
-const char* VMInspector::getTypeName(JSValue value)
-{
- if (value.isInt32())
- return "<Int32>";
- if (value.isBoolean())
- return "<Boolean>";
- if (value.isNull())
- return "<Empty>";
- if (value.isUndefined())
- return "<Undefined>";
- if (value.isCell())
- return "<Cell>";
- if (value.isEmpty())
- return "<Empty>";
- return "";
-}
-
-void VMInspector::dumpFrame0(CallFrame* frame)
-{
- dumpFrame(frame, 0, 0, 0, 0);
-}
-
-void VMInspector::dumpFrame(CallFrame* frame, const char* prefix,
- const char* funcName, const char* file, int line)
-{
- int frameCount = VMInspector::countFrames(frame);
- if (frameCount < 0)
- return;
-
- Instruction* vPC = 0;
- if (frame->codeBlock())
- vPC = frame->currentVPC();
-
- #define CAST reinterpret_cast
-
- if (prefix)
- printf("%s ", prefix);
-
- printf("frame [%d] %p { cb %p:%s, retPC %p:%s, scope %p:%s, callee %p:%s, callerFrame %p:%s, argc %d, vPC %p }",
- frameCount, frame,
- CAST<void*>(frame[JSStack::CodeBlock].payload()),
- getTypeName(frame[JSStack::CodeBlock].jsValue()),
- CAST<void*>(frame[JSStack::ReturnPC].payload()),
- getTypeName(frame[JSStack::ReturnPC].jsValue()),
- CAST<void*>(frame[JSStack::ScopeChain].payload()),
- getTypeName(frame[JSStack::ScopeChain].jsValue()),
- CAST<void*>(frame[JSStack::Callee].payload()),
- getTypeName(frame[JSStack::Callee].jsValue()),
- CAST<void*>(frame[JSStack::CallerFrame].callFrame()),
- getTypeName(frame[JSStack::CallerFrame].jsValue()),
- frame[JSStack::ArgumentCount].payload(),
- vPC);
-
- if (funcName || file || (line >= 0)) {
- printf(" @");
- if (funcName)
- printf(" %s", funcName);
- if (file)
- printf(" %s", file);
- if (line >= 0)
- printf(":%d", line);
- }
- printf("\n");
-}
-
-int VMInspector::countFrames(CallFrame* frame)
-{
- int count = -1;
- while (frame && !frame->isVMEntrySentinel()) {
- count++;
- frame = frame->callerFrame();
- }
- return count;
-}
-
-
-//============================================================================
-// class FormatPrinter
-// - implements functionality to support fprintf.
-//
-// The FormatPrinter classes do the real formatting and printing.
-// By default, the superclass FormatPrinter will print to stdout (printf).
-// Each of the subclass will implement the other ...printf() options.
-// The subclasses are:
-//
-// FileFormatPrinter - fprintf
-// StringFormatPrinter - sprintf
-// StringNFormatPrinter - snprintf
-
-class FormatPrinter {
-public:
- virtual ~FormatPrinter() { }
-
- void print(const char* format, va_list args);
-
-protected:
- // Low level printers:
- bool printArg(const char* format, ...);
- virtual bool printArg(const char* format, va_list args);
-
- // JS type specific printers:
- void printWTFString(va_list args, bool verbose);
-};
-
-
-// The public print() function is the real workhorse behind the printf
-// family of functions. print() deciphers the % formatting, translate them
-// to primitive formats, and dispatches to underlying printArg() functions
-// to do the printing.
-//
-// The non-public internal printArg() function is virtual and is responsible
-// for handling the variations between printf, fprintf, sprintf, and snprintf.
-
-void FormatPrinter::print(const char* format, va_list args)
-{
- const char* p = format;
- const char* errorStr;
-
- // buffer is only used for 2 purposes:
- // 1. To temporarily hold a copy of normal chars (not needing formatting)
- // to be passed to printArg() and printed.
- //
- // The incoming format string may contain a string of normal chars much
- // longer than 128, but we handle this by breaking them out to 128 chars
- // fragments and printing each fragment before re-using the buffer to
- // load up the next fragment.
- //
- // 2. To hold a single "%..." format to be passed to printArg() to process
- // a single va_arg.
-
- char buffer[129]; // 128 chars + null terminator.
- char* end = &buffer[sizeof(buffer) - 1];
- const char* startOfFormatSpecifier = 0;
-
- while (true) {
- char c = *p++;
- char* curr = buffer;
-
- // Print leading normal chars:
- while (c != '\0' && c != '%') {
- *curr++ = c;
- if (curr == end) {
- // Out of buffer space. Flush the fragment, and start over.
- *curr = '\0';
- bool success = printArg("%s", buffer);
- if (!success) {
- errorStr = buffer;
- goto handleError;
- }
- curr = buffer;
- }
- c = *p++;
- }
- // If we have stuff in the buffer, flush the fragment:
- if (curr != buffer) {
- ASSERT(curr < end + 1);
- *curr = '\0';
- bool success = printArg("%s", buffer);
- if (!success) {
- errorStr = buffer;
- goto handleError;
- }
- }
-
- // End if there are not more chars to print:
- if (c == '\0')
- break;
-
- // If we get here, we've must have seen a '%':
- startOfFormatSpecifier = p - 1;
- ASSERT(*startOfFormatSpecifier == '%');
- c = *p++;
-
- // Check for "%%" case:
- if (c == '%') {
- bool success = printArg("%c", '%');
- if (!success) {
- errorStr = p - 2;
- goto handleError;
- }
- continue;
- }
-
- // Check for JS (%J<x>) formatting extensions:
- if (c == 'J') {
- bool verbose = false;
-
- c = *p++;
- if (UNLIKELY(c == '\0')) {
- errorStr = p - 2; // Rewind to % in "%J\0"
- goto handleError;
- }
-
- if (c == '+') {
- verbose = true;
- c= *p++;
- if (UNLIKELY(c == '\0')) {
- errorStr = p - 3; // Rewind to % in "%J+\0"
- goto handleError;
- }
- }
-
- switch (c) {
- // %Js - WTF::String*
- case 's': {
- printWTFString(args, verbose);
- continue;
- }
- } // END switch.
-
- // Check for non-JS extensions:
- } else if (c == 'b') {
- int value = va_arg(args, int);
- printArg("%s", value ? "TRUE" : "FALSE");
- continue;
- }
-
- // If we didn't handle the format in one of the above cases,
- // rewind p and let the standard formatting check handle it
- // if possible:
- p = startOfFormatSpecifier;
- ASSERT(*p == '%');
-
- // Check for standard formatting:
- // A format specifier always starts with a % and ends with some
- // alphabet. We'll do the simple thing and scan until the next
- // alphabet, or the end of string.
-
- // In the following, we're going to use buffer as storage for a copy
- // of a single format specifier. Hence, conceptually, we can think of
- // 'buffer' as synonymous with 'argFormat' here:
-
-#define ABORT_IF_FORMAT_TOO_LONG(curr) \
- do { \
- if (UNLIKELY(curr >= end)) \
- goto formatTooLong; \
- } while (false)
-
- curr = buffer;
- *curr++ = *p++; // Output the first % in the format specifier.
- c = *p++; // Grab the next char in the format specifier.
-
- // Checks for leading modifiers e.g. "%-d":
- // 0, -, ' ', +, '\''
- if (c == '0' || c == '-' || c == ' ' || c == '+' || c == '\'' || c == '#') {
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- c = *p++;
- }
-
- // Checks for decimal digit field width modifiers e.g. "%2f":
- while (c >= '0' && c <= '9') {
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- c = *p++;
- }
-
- // Checks for '.' e.g. "%2.f":
- if (c == '.') {
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- c = *p++;
-
- // Checks for decimal digit precision modifiers e.g. "%.2f":
- while (c >= '0' && c <= '9') {
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- c = *p++;
- }
- }
-
- // Checks for the modifier <m> where <m> can be:
- // l, h, j, t, z
- // e.g. "%ld"
- if (c == 'l' || c == 'h' || c == 'j' || c == 't' || c == 'z' || c == 'L') {
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- char prevChar = c;
- c = *p++;
-
- // Checks for the modifier ll or hh in %<x><m>:
- if ((prevChar == 'l' || prevChar == 'h') && c == prevChar) {
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- c = *p++;
- }
- }
-
- // Checks for %<x> where <x> can be:
- // d, i, n, o, u, x, X
- // But hey, we're just going to do the simple thing and allow any
- // alphabet. The user is expected to pass correct format specifiers.
- // We won't do any format checking here. We'll just pass it on, and the
- // underlying ...printf() implementation may do the needed checking
- // at its discretion.
- while (c != '\0' && !isASCIIAlpha(c)) {
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- c = *p++;
- }
-
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr++ = c;
- if (c == '\0') {
- // Uh oh. Bad format. We should have gotten an alphabet instead.
- // Print the supposed format as a string instead:
- errorStr = buffer;
- goto handleError;
- }
-
- // Otherwise, we have the alpha that terminates the format.
- // Terminate the buffer (i.e. argFormat) string:
- ASSERT(isASCIIAlpha(c));
- ABORT_IF_FORMAT_TOO_LONG(curr);
- *curr = '\0';
-
- bool success = printArg(buffer, args);
- if (!success) {
- errorStr = buffer;
- goto handleError;
- }
- }
-#undef ABORT_IF_FORMAT_TOO_LONG
-
- return;
-
-formatTooLong:
- // Print the error string:
- ASSERT(!!startOfFormatSpecifier);
- p = startOfFormatSpecifier;
- ASSERT(p >= format);
- printArg("ERROR @ Format too long at \"%s\"\n", p);
- return;
-
-handleError:
- // We've got an error. Can't do any more work. Print an error message if
- // possible and then just return.
-
- // The errorStr may be pointing into the middle of buffer, or the original
- // format string. Move the string to buffer for consistency, and also so
- // that we can strip it of newlines below.
- if (errorStr != buffer) {
- size_t length = strlen(errorStr);
- if (length > sizeof(buffer) - 1)
- length = sizeof(buffer) - 1;
- memmove(buffer, errorStr, length);
- buffer[length] = '\0'; // Terminate the moved error string.
- }
- // Strip the newlines:
- char* cp = buffer;
- while (*cp) {
- if (*cp == '\n' || *cp == '\r')
- *cp = ' ';
- cp++;
- }
- // Print the error string:
- printArg("ERROR @ \"%s\"\n", buffer);
-}
-
-
-bool FormatPrinter::printArg(const char* format, ...)
-{
- va_list args;
- va_start(args, format);
- bool success = printArg(format, args);
- va_end(args);
- return success;
-}
-
-bool FormatPrinter::printArg(const char* format, va_list args)
-{
- int count = ::vprintf(format, args);
- return (count >= 0); // Fail if less than 0 chars printed.
-}
-
-
-// %Js - WTF::String*
-// verbose mode prints: WTF::String "<your string>"
-void FormatPrinter::printWTFString(va_list args, bool verbose)
-{
- const String* str = va_arg(args, const String*);
-
- // Print verbose header if appropriate:
- if (verbose)
- printArg("WTF::String \"");
-
- // Print the string itself:
- if (!str->isEmpty()) {
- if (str->is8Bit()) {
- const LChar* chars = str->characters8();
- printArg("%s", reinterpret_cast<const char*>(chars));
- } else {
- const UChar* chars = str->characters16();
- printArg("%S", reinterpret_cast<const wchar_t*>(chars));
- }
- }
-
- // Print verbose footer if appropriate:
- if (verbose)
- printArg("\"");
-}
-
-
-//============================================================================
-// class FileFormatPrinter
-// - implements functionality to support fprintf.
-
-class FileFormatPrinter: public FormatPrinter {
-public:
- FileFormatPrinter(FILE*);
-private:
- virtual bool printArg(const char* format, va_list args);
-
- FILE* m_file;
-};
-
-FileFormatPrinter::FileFormatPrinter(FILE* file)
- : m_file(file)
-{
-}
-
-bool FileFormatPrinter::printArg(const char* format, va_list args)
-{
- int count = ::vfprintf(m_file, format, args);
- return (count >= 0); // Fail if less than 0 chars printed.
-}
-
-
-//============================================================================
-// class StringFormatPrinter
-// - implements functionality to support sprintf.
-
-class StringFormatPrinter: public FormatPrinter {
-public:
- StringFormatPrinter(char* buffer);
-private:
- virtual bool printArg(const char* format, va_list args);
-
- char* m_buffer;
-};
-
-StringFormatPrinter::StringFormatPrinter(char* buffer)
- : m_buffer(buffer)
-{
-}
-
-bool StringFormatPrinter::printArg(const char* format, va_list args)
-{
- int count = ::vsprintf(m_buffer, format, args);
- m_buffer += count;
- return (count >= 0); // Fail if less than 0 chars printed.
-}
-
-
-//============================================================================
-// class StringNFormatPrinter
-// - implements functionality to support snprintf.
-
-class StringNFormatPrinter: public FormatPrinter {
-public:
- StringNFormatPrinter(char* buffer, size_t);
-private:
- virtual bool printArg(const char* format, va_list args);
-
- char* m_buffer;
- size_t m_size;
-};
-
-
-StringNFormatPrinter::StringNFormatPrinter(char* buffer, size_t size)
- : m_buffer(buffer)
- , m_size(size)
-{
-}
-
-bool StringNFormatPrinter::printArg(const char* format, va_list args)
-{
- if (m_size > 0) {
- int count = ::vsnprintf(m_buffer, m_size, format, args);
-
- // According to vsnprintf specs, ...
- bool success = (count >= 0);
- if (static_cast<size_t>(count) >= m_size) {
- // If count > size, then we didn't have enough buffer space.
- count = m_size;
- }
-
- // Adjust the buffer to what's left if appropriate:
- if (success) {
- m_buffer += count;
- m_size -= count;
- }
- return success;
- }
- // No more room to print. Declare it a fail:
- return false;
-}
-
-
-//============================================================================
-// VMInspector printf family of methods:
-
-void VMInspector::fprintf(FILE* file, const char* format, ...)
-{
- va_list args;
- va_start(args, format);
- FileFormatPrinter(file).print(format, args);
- va_end(args);
-}
-
-void VMInspector::printf(const char* format, ...)
-{
- va_list args;
- va_start(args, format);
- FormatPrinter().print(format, args);
- va_end(args);
-}
-
-void VMInspector::sprintf(char* buffer, const char* format, ...)
-{
- va_list args;
- va_start(args, format);
- StringFormatPrinter(buffer).print(format, args);
- va_end(args);
-}
-
-void VMInspector::snprintf(char* buffer, size_t size, const char* format, ...)
-{
- va_list args;
- va_start(args, format);
- StringNFormatPrinter(buffer, size).print(format, args);
- va_end(args);
-}
-
-} // namespace JSC
-
-#endif // ENABLE(VMINSPECTOR)