diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/JavaScriptCore/interpreter/VMInspector.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/JavaScriptCore/interpreter/VMInspector.cpp')
-rw-r--r-- | Source/JavaScriptCore/interpreter/VMInspector.cpp | 572 |
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) |