]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - interpreter/CallFrame.cpp
JavaScriptCore-7600.1.4.9.tar.gz
[apple/javascriptcore.git] / interpreter / CallFrame.cpp
index 972487565f5aacacb25898c190e49a88fc32cedc..df19d7fce144e208bf04b862701c8a22e992e6bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2013, 2014 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "CallFrame.h"
 
+#include "CallFrameInlines.h"
 #include "CodeBlock.h"
 #include "Interpreter.h"
+#include "JSActivation.h"
+#include "JSCInlines.h"
+#include "VMEntryScope.h"
+#include <wtf/StringPrintStream.h>
 
 namespace JSC {
 
-JSValue CallFrame::thisValue()
+#ifndef NDEBUG
+JSStack* CallFrame::stack()
 {
-    return this[codeBlock()->thisRegister()].jsValue();
+    return &interpreter()->stack();
 }
 
-#ifndef NDEBUG
-void CallFrame::dumpCaller()
+#endif
+
+#if USE(JSVALUE32_64)
+unsigned CallFrame::locationAsBytecodeOffset() const
+{
+    ASSERT(codeBlock());
+    ASSERT(hasLocationAsBytecodeOffset());
+    return currentVPC() - codeBlock()->instructions().begin();
+}
+
+void CallFrame::setLocationAsBytecodeOffset(unsigned offset)
 {
-    int signedLineNumber;
-    intptr_t sourceID;
-    UString urlString;
-    JSValue function;
+    ASSERT(codeBlock());
+    setCurrentVPC(codeBlock()->instructions().begin() + offset);
+    ASSERT(hasLocationAsBytecodeOffset());
+}
+#else
+Instruction* CallFrame::currentVPC() const
+{
+    return codeBlock()->instructions().begin() + locationAsBytecodeOffset();
+}
+void CallFrame::setCurrentVPC(Instruction* vpc)
+{
+    setLocationAsBytecodeOffset(vpc - codeBlock()->instructions().begin());
+}
+#endif
     
-    interpreter()->retrieveLastCaller(this, signedLineNumber, sourceID, urlString, function);
-    printf("Callpoint => %s:%d\n", urlString.ascii(), signedLineNumber);
+#if ENABLE(DFG_JIT)
+unsigned CallFrame::bytecodeOffsetFromCodeOriginIndex()
+{
+    ASSERT(hasLocationAsCodeOriginIndex());
+    CodeBlock* codeBlock = this->codeBlock();
+    ASSERT(codeBlock);
+
+    CodeOrigin codeOrigin;
+    unsigned index = locationAsCodeOriginIndex();
+    ASSERT(codeBlock->canGetCodeOrigin(index));
+    codeOrigin = codeBlock->codeOrigin(index);
+
+    for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) {
+        if (inlineCallFrame->baselineCodeBlock() == codeBlock)
+            return codeOrigin.bytecodeIndex;
+
+        codeOrigin = inlineCallFrame->caller;
+        inlineCallFrame = codeOrigin.inlineCallFrame;
+    }
+    return codeOrigin.bytecodeIndex;
 }
+
+#endif // ENABLE(DFG_JIT)
+
+unsigned CallFrame::bytecodeOffset()
+{
+    if (!codeBlock())
+        return 0;
+#if ENABLE(DFG_JIT)
+    if (hasLocationAsCodeOriginIndex())
+        return bytecodeOffsetFromCodeOriginIndex();
 #endif
+    return locationAsBytecodeOffset();
+}
+
+CodeOrigin CallFrame::codeOrigin()
+{
+    if (!codeBlock())
+        return CodeOrigin(0);
+#if ENABLE(DFG_JIT)
+    if (hasLocationAsCodeOriginIndex()) {
+        unsigned index = locationAsCodeOriginIndex();
+        ASSERT(codeBlock()->canGetCodeOrigin(index));
+        return codeBlock()->codeOrigin(index);
+    }
+#endif
+    return CodeOrigin(locationAsBytecodeOffset());
+}
+
+Register* CallFrame::topOfFrameInternal()
+{
+    CodeBlock* codeBlock = this->codeBlock();
+    ASSERT(codeBlock);
+    return registers() + codeBlock->stackPointerOffset();
+}
+
+JSGlobalObject* CallFrame::vmEntryGlobalObject()
+{
+    if (this == lexicalGlobalObject()->globalExec())
+        return lexicalGlobalObject();
+
+    // For any ExecState that's not a globalExec, the 
+    // dynamic global object must be set since code is running
+    ASSERT(vm().entryScope);
+    return vm().entryScope->globalObject();
+}
+
+JSActivation* CallFrame::activation() const
+{
+    CodeBlock* codeBlock = this->codeBlock();
+    RELEASE_ASSERT(codeBlock->needsActivation());
+    VirtualRegister activationRegister = codeBlock->activationRegister();
+    return registers()[activationRegister.offset()].Register::activation();
+}
+
+void CallFrame::setActivation(JSActivation* activation)
+{
+    CodeBlock* codeBlock = this->codeBlock();
+    RELEASE_ASSERT(codeBlock->needsActivation());
+    VirtualRegister activationRegister = codeBlock->activationRegister();
+    registers()[activationRegister.offset()] = activation;
+}
+
+void CallFrame::dump(PrintStream& out)
+{
+    if (CodeBlock* codeBlock = this->codeBlock()) {
+        out.print(codeBlock->inferredName(), "#", codeBlock->hashAsStringIfPossible(), " [", codeBlock->jitType(), "]");
+
+        out.print("(");
+        thisValue().dumpForBacktrace(out);
+
+        for (size_t i = 0; i < argumentCount(); ++i) {
+            out.print(", ");
+            JSValue value = argument(i);
+            value.dumpForBacktrace(out);
+        }
+
+        out.print(")");
 
+        return;
+    }
+
+    out.print(returnPC());
 }
+
+const char* CallFrame::describeFrame()
+{
+    const size_t bufferSize = 200;
+    static char buffer[bufferSize + 1];
+    
+    WTF::StringPrintStream stringStream;
+
+    dump(stringStream);
+
+    strncpy(buffer, stringStream.toCString().data(), bufferSize);
+    buffer[bufferSize] = '\0';
+    
+    return buffer;
+}
+
+} // namespace JSC