Add support for line and file information in backtraces.
authorDavid Anderson <dvander@alliedmods.net>
Thu Jul 12 00:38:00 2012 -0700 (2012-07-12)
changeset 701aec996cde2d
parent 69 dfce0539a77d
child 71 f7e573226c2b
Add support for line and file information in backtraces.
jitcraft/API.cpp
jitcraft/BytecodeCompiler.cpp
jitcraft/BytecodeEmitter.cpp
jitcraft/BytecodeEmitter.h
jitcraft/Code.h
jitcraft/CompactBuffer.h
jitcraft/Modules.cpp
jitcraft/Modules.h
jitcraft/ObjectVisitor.h
jitcraft/Opcodes.cpp
jitcraft/Stack.cpp
jitcraft/Token.h
jitcraft/Vector.h
jitcraft/jitcraft.vcxproj
     1.1 --- a/jitcraft/API.cpp	Wed Jul 11 01:12:54 2012 -0700
     1.2 +++ b/jitcraft/API.cpp	Thu Jul 12 00:38:00 2012 -0700
     1.3 @@ -30,6 +30,7 @@
     1.4  #include "Array.h"
     1.5  #include "Interpreter.h"
     1.6  #include "Stack.h"
     1.7 +#include "Strings.h"
     1.8  
     1.9  using namespace ke;
    1.10  
    1.11 @@ -155,6 +156,11 @@
    1.12      if (!module)
    1.13          return Ke::Local<Ke::Module>();
    1.14  
    1.15 +    ke::Local<ke::String> pathstr(ZONE(), ke::String::New(ZONE(), path, Heap::Tenure_Old));
    1.16 +    if (!pathstr)
    1.17 +        return Ke::Local<Ke::Module>();
    1.18 +
    1.19 +    module->setPath(pathstr);
    1.20      return ToLocal<ke::Module, Ke::Module>(module);
    1.21  }
    1.22  
     2.1 --- a/jitcraft/BytecodeCompiler.cpp	Wed Jul 11 01:12:54 2012 -0700
     2.2 +++ b/jitcraft/BytecodeCompiler.cpp	Thu Jul 12 00:38:00 2012 -0700
     2.3 @@ -199,6 +199,7 @@
     2.4          }
     2.5      } else {
     2.6          IndexExpression *index = node->lvalue()->toIndexExpression();
     2.7 +        __ note_position(index->pos());
     2.8  
     2.9          // Note: Eventually, watch out for a whole here. An expression like:
    2.10          //
    2.11 @@ -226,6 +227,7 @@
    2.12          visitForALU(node->type(), node->expression());
    2.13  
    2.14          TokenKind alu = TokenKind(int(node->token()) - (TOK_ASSIGN_ADD - TOK_PLUS));
    2.15 +        __ note_position(node->pos());
    2.16          __ binary(TokenToOpcode(alu));
    2.17      }
    2.18  
    2.19 @@ -233,6 +235,7 @@
    2.20      if (node->expression()->type()->isArray()) {
    2.21          // Unlike references, which can only be computed from a NamePRoxy,
    2.22          // arrays can be computed from multiple lvalue types.
    2.23 +        __ note_position(node->pos());
    2.24          __ arraycopy();
    2.25      } else if (node->lvalue()->isNameProxy()) {
    2.26          NameProxy *proxy = node->lvalue()->toNameProxy();
    2.27 @@ -305,6 +308,8 @@
    2.28          }
    2.29      } else {
    2.30          IndexExpression *index = expr->toIndexExpression();
    2.31 +        __ note_position(index->pos());
    2.32 +
    2.33          index->left()->accept(this);
    2.34          index->right()->accept(this);
    2.35  
    2.36 @@ -332,6 +337,7 @@
    2.37          __ int_(1);
    2.38      }
    2.39  
    2.40 +    __ note_position(node->pos());
    2.41      if (node->token() == TOK_INCREMENT)
    2.42          __ binary(OP_ADD);
    2.43      else
    2.44 @@ -374,6 +380,8 @@
    2.45      Opcode op = TokenToOpcode(node->token());
    2.46      if (node->type()->isFloat())
    2.47          op = (Opcode)(int(op) + (OP_ADD_F - OP_ADD));
    2.48 +
    2.49 +    __ note_position(node->pos());
    2.50      __ binary(op);
    2.51  }
    2.52  
    2.53 @@ -382,6 +390,7 @@
    2.54  {
    2.55      node->left()->accept(this);
    2.56      node->right()->accept(this);
    2.57 +    __ note_position(node->pos());
    2.58      __ bounds();
    2.59  
    2.60      if (node->type()->isArray())
    2.61 @@ -558,6 +567,7 @@
    2.62      assert(array->nelements() >= node->string()->length());
    2.63      memcpy(array->chars(), node->string()->raw(), node->string()->length() * sizeof(char));
    2.64  
    2.65 +    __ note_position(node->pos());
    2.66      __ object(array);
    2.67  }
    2.68  
    2.69 @@ -570,10 +580,12 @@
    2.70      Local<Type> type(zone_, var->type());
    2.71      if (type->isArray()) {
    2.72          Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
    2.73 +        __ note_position(node->pos());
    2.74          __ newarray_lifo(map);
    2.75  
    2.76          if (node->initialization()) {
    2.77              node->initialization()->accept(this);
    2.78 +            __ note_position(node->pos());
    2.79              __ arraycopy();
    2.80          }
    2.81      } else {
    2.82 @@ -622,11 +634,13 @@
    2.83                  // :TODO: test with functions and globals
    2.84                  // Compute a reference to the name.
    2.85                  Variable *var = arg->toNameProxy()->binding()->toVariable();
    2.86 +                __ note_position(node->pos());
    2.87                  __ newref(var);
    2.88              } else if (arg->isIndexExpression()) {
    2.89                  IndexExpression *expr = arg->toIndexExpression();
    2.90                  expr->left()->accept(this);
    2.91                  expr->right()->accept(this);
    2.92 +                __ note_position(expr->pos());
    2.93                  __ bounds();
    2.94                  __ arrayref_lifo();
    2.95              } else {
    2.96 @@ -634,6 +648,7 @@
    2.97                  // this type. Make an indirect one, by taking the top of the
    2.98                  // stack and boxing it up.
    2.99                  arg->accept(this);
   2.100 +                __ note_position(node->pos());
   2.101                  __ slotref_lifo();
   2.102              }
   2.103          } else {
   2.104 @@ -643,6 +658,7 @@
   2.105  
   2.106      NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
   2.107  
   2.108 +    __ note_position(node->pos());
   2.109      if (fun->isNative())
   2.110          __ callnative(fun->slot(), node->arguments()->length());
   2.111      else
   2.112 @@ -712,6 +728,8 @@
   2.113      // Note: No need to record a life slot here, since it's part of the Frame.
   2.114      AutoEnterScope functionScope(this, node->scope());
   2.115  
   2.116 +    // Set the initial line, because line mappings are deltas.
   2.117 +    __ setFirstLine(node->pos().line);
   2.118      locals_ = FixedArray::New(zone_, node->scope()->maxContainedLocals(), Heap::Tenure_Old);
   2.119  
   2.120      node->body()->accept(this);
   2.121 @@ -774,8 +792,26 @@
   2.122          assert(cursor == safepoints->raw() + gcmapSize);
   2.123      }
   2.124  
   2.125 -    Local<Code> code(zone_, Code::New(zone_, bytes, locals_, objects, __ maxStackDepth(),
   2.126 -                     moduleData_->module, safepoints));
   2.127 +    Local<ByteArray> sourcemap(zone_);
   2.128 +    if (__ sourcemapLength()) {
   2.129 +        sourcemap = ByteArray::New(zone_, __ sourcemapLength(), Heap::Tenure_Old);
   2.130 +        if (!sourcemap)
   2.131 +            return NULL;
   2.132 +
   2.133 +        memcpy(sourcemap->raw(), __ sourcemap(), __ sourcemapLength());
   2.134 +    }
   2.135 +
   2.136 +    Local<Code> code(zone_);
   2.137 +
   2.138 +    code = Code::New(zone_,
   2.139 +                     bytes,
   2.140 +                     locals_,
   2.141 +                     objects,
   2.142 +                     __ maxStackDepth(),
   2.143 +                     moduleData_->module,
   2.144 +                     safepoints,
   2.145 +                     sourcemap,
   2.146 +                     node->pos().line);
   2.147      if (!code)
   2.148          return NULL;
   2.149  
     3.1 --- a/jitcraft/BytecodeEmitter.cpp	Wed Jul 11 01:12:54 2012 -0700
     3.2 +++ b/jitcraft/BytecodeEmitter.cpp	Thu Jul 12 00:38:00 2012 -0700
     3.3 @@ -32,6 +32,8 @@
     3.4      oom_(false),
     3.5      maxStackDepth_(0)
     3.6  {
     3.7 +    lastCodePosition_ = 0;
     3.8 +    firstLine_ = 1;
     3.9  }
    3.10  
    3.11  bool
    3.12 @@ -95,3 +97,18 @@
    3.13      oom_ &= oopRecords_.append(record);
    3.14  }
    3.15  
    3.16 +void
    3.17 +BytecodeEmitter::note_position(const SourcePosition &pos)
    3.18 +{
    3.19 +    assert(pos.line > 0);
    3.20 +    assert(unsigned(pos.line) >= firstLine_);
    3.21 +
    3.22 +    unsigned lineDelta = unsigned(pos.line) - firstLine_;
    3.23 +    unsigned pcDelta = unsigned(position()) - lastCodePosition_;
    3.24 +
    3.25 +    sourcemap_.writeUint32(pcDelta);
    3.26 +    sourcemap_.writeUint32(lineDelta);
    3.27 +    sourcemap_.writeUint32(pos.col);
    3.28 +
    3.29 +    lastCodePosition_ = unsigned(position());
    3.30 +}
     4.1 --- a/jitcraft/BytecodeEmitter.h	Wed Jul 11 01:12:54 2012 -0700
     4.2 +++ b/jitcraft/BytecodeEmitter.h	Thu Jul 12 00:38:00 2012 -0700
     4.3 @@ -24,6 +24,7 @@
     4.4  #include "Opcodes.h"
     4.5  #include "NameBinding.h"
     4.6  #include "Handles.h"
     4.7 +#include "CompactBuffer.h"
     4.8  
     4.9  namespace ke {
    4.10  
    4.11 @@ -60,6 +61,9 @@
    4.12      ObjectList objects_;
    4.13      PoolList<bool> oopMap_;
    4.14      PoolList<OopRecord *> oopRecords_;
    4.15 +    CompactBufferWriter sourcemap_;
    4.16 +    unsigned lastCodePosition_;
    4.17 +    unsigned firstLine_;
    4.18  
    4.19    private:
    4.20      // The maximum size of a code object must be such that the distance between
    4.21 @@ -111,7 +115,8 @@
    4.22      void writeObject(Object *obj) {
    4.23          writeUint32(objects_.length());
    4.24          ScopedRoot<Object> root(obj);
    4.25 -        oom_ &= objects_.append(root);
    4.26 +        if (!objects_.append(root))
    4.27 +            oom_ = true;
    4.28      }
    4.29  
    4.30      int position() const {
    4.31 @@ -129,7 +134,7 @@
    4.32          return unsigned(buffer_pos_ - buffer_);
    4.33      }
    4.34      bool oom() const {
    4.35 -        return oom_;
    4.36 +        return oom_ || sourcemap_.oom();
    4.37      }
    4.38      unsigned stackDepth() const {
    4.39          return oopMap_.length();
    4.40 @@ -150,6 +155,18 @@
    4.41              oopMap_.pop();
    4.42      }
    4.43  
    4.44 +    void note_position(const SourcePosition &pos);
    4.45 +    uint8 *sourcemap() const {
    4.46 +        return sourcemap_.buffer();
    4.47 +    }
    4.48 +    size_t sourcemapLength() const {
    4.49 +        return sourcemap_.length();
    4.50 +    }
    4.51 +    void setFirstLine(unsigned line) {
    4.52 +        assert(!sourcemap_.length());
    4.53 +        firstLine_ = line;
    4.54 +    }
    4.55 +
    4.56    public:
    4.57      // A label represents a local control-flow target in the bytecode. A label
    4.58      // may be in three states:
     5.1 --- a/jitcraft/Code.h	Wed Jul 11 01:12:54 2012 -0700
     5.2 +++ b/jitcraft/Code.h	Thu Jul 12 00:38:00 2012 -0700
     5.3 @@ -24,6 +24,7 @@
     5.4  #include "Heap.h"
     5.5  #include "Types.h"
     5.6  #include "FixedArray.h"
     5.7 +#include "Token.h"
     5.8  
     5.9  namespace ke {
    5.10  
    5.11 @@ -40,7 +41,9 @@
    5.12      Barriered<FixedArray> locals_;
    5.13      Barriered<FixedArray> objects_;
    5.14      Barriered<ByteArray> safepoints_;
    5.15 +    Barriered<ByteArray> sourcemap_;
    5.16      unsigned maxStackDepth_;
    5.17 +    unsigned lineNumber_;
    5.18  
    5.19    public:
    5.20      static inline size_t BytesPerSafepoint(size_t stackDepth) {
    5.21 @@ -50,7 +53,8 @@
    5.22    public:
    5.23      static Code *New(Zone *zone, Handle<ByteArray> bytecode, Handle<FixedArray> locals,
    5.24                       Handle<FixedArray> objects, unsigned maxStackDepth, Handle<Module> module,
    5.25 -                     Handle<ByteArray> safepoints);
    5.26 +                     Handle<ByteArray> safepoints, Handle<ByteArray> sourcemap,
    5.27 +                     unsigned lineNumber);
    5.28  
    5.29      Module *module() {
    5.30          return module_;
    5.31 @@ -86,6 +90,11 @@
    5.32          return pc - start();
    5.33      }
    5.34  
    5.35 +    SourcePosition pcToSource(unsigned pc);
    5.36 +    unsigned lineNumber() {
    5.37 +        return lineNumber_;
    5.38 +    }
    5.39 +
    5.40      // GC Descriptor.
    5.41      static inline size_t offsetOfModule() {
    5.42          return offsetof(Code, module_);
    5.43 @@ -102,6 +111,9 @@
    5.44      static inline size_t offsetOfSafepoints() {
    5.45          return offsetof(Code, safepoints_);
    5.46      }
    5.47 +    static inline size_t offsetOfSourceMap() {
    5.48 +        return offsetof(Code, sourcemap_);
    5.49 +    }
    5.50      // End GC Descriptor.
    5.51  
    5.52      static Code *cast(Object *obj) {
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/jitcraft/CompactBuffer.h	Thu Jul 12 00:38:00 2012 -0700
     6.3 @@ -0,0 +1,100 @@
     6.4 +/* vim: set ts=4 sw=4 tw=99 et:
     6.5 + *
     6.6 + * Copyright (C) 2012 David Anderson
     6.7 + *
     6.8 + * This file is part of JITCraft.
     6.9 + *
    6.10 + * JITCraft is free software: you can redistribute it and/or modify it under
    6.11 + * the terms of the GNU General Public License as published by the Free
    6.12 + * Software Foundation, either version 3 of the License, or (at your option)
    6.13 + * any later version.
    6.14 + * 
    6.15 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    6.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    6.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    6.18 + *
    6.19 + * You should have received a copy of the GNU General Public License along with
    6.20 + * JITCraft. If not, see http://www.gnu.org/licenses/.
    6.21 + */
    6.22 +#ifndef _include_jc_compact_buffer_h_
    6.23 +#define _include_jc_compact_buffer_h_
    6.24 +
    6.25 +#include "AllocatorPolicies.h"
    6.26 +#include "Utility.h"
    6.27 +#include "Vector.h"
    6.28 +
    6.29 +namespace ke {
    6.30 +
    6.31 +class CompactBufferReader
    6.32 +{
    6.33 +    const uint8 *pos_;
    6.34 +    const uint8 *end_;
    6.35 +
    6.36 +  public:
    6.37 +    CompactBufferReader(const uint8 *start, const uint8 *end)
    6.38 +      : pos_(start),
    6.39 +        end_(end)
    6.40 +    {
    6.41 +    }
    6.42 +
    6.43 +    uint8 readUint8() {
    6.44 +        assert(pos_ < end_);
    6.45 +        return *pos_++;
    6.46 +    }
    6.47 +
    6.48 +    uint32 readUint32() {
    6.49 +        uint32 value = 0;
    6.50 +        uint32 shift = 0;
    6.51 +
    6.52 +        uint8 byte;
    6.53 +        do {
    6.54 +            byte = readUint8();
    6.55 +            value |= (byte >> 1) << shift;
    6.56 +            shift += 7;
    6.57 +        } while (byte & 1);
    6.58 +
    6.59 +        assert(shift < 32);
    6.60 +        return value;
    6.61 +    }
    6.62 +
    6.63 +    bool done() const {
    6.64 +        return pos_ == end_;
    6.65 +    }
    6.66 +};
    6.67 +
    6.68 +class CompactBufferWriter
    6.69 +{
    6.70 +    Vector<uint8, ZoneAllocatorPolicy> buffer_;
    6.71 +    bool enoughMemory_;
    6.72 +
    6.73 +  public:
    6.74 +    CompactBufferWriter()
    6.75 +      : enoughMemory_(true)
    6.76 +    {
    6.77 +    }
    6.78 +
    6.79 +    void writeUint8(unsigned value) {
    6.80 +        enoughMemory_ &= buffer_.append(value);
    6.81 +    }
    6.82 +    void writeUint32(unsigned value) {
    6.83 +        do {
    6.84 +            writeUint8(((value & 0x7F) << 1) | (value > 0x7F));
    6.85 +            value >>= 7;
    6.86 +        } while (value);
    6.87 +    }
    6.88 +
    6.89 +    uint8 *buffer() const {
    6.90 +        return buffer_.buffer();
    6.91 +    }
    6.92 +    size_t length() const {
    6.93 +        return buffer_.length();
    6.94 +    }
    6.95 +
    6.96 +    bool oom() const {
    6.97 +        return !enoughMemory_;
    6.98 +    }
    6.99 +};
   6.100 +
   6.101 +}
   6.102 +
   6.103 +#endif // _include_jc_compact_buffer_h_
     7.1 --- a/jitcraft/Modules.cpp	Wed Jul 11 01:12:54 2012 -0700
     7.2 +++ b/jitcraft/Modules.cpp	Thu Jul 12 00:38:00 2012 -0700
     7.3 @@ -34,6 +34,7 @@
     7.4          return NULL;
     7.5  
     7.6      module->functions_ = functions;
     7.7 +    module->file_ = NULL;
     7.8      module->publics_ = NULL;
     7.9      module->natives_ = NULL;
    7.10      module->nativeIdentity_ = NULL;
     8.1 --- a/jitcraft/Modules.h	Wed Jul 11 01:12:54 2012 -0700
     8.2 +++ b/jitcraft/Modules.h	Thu Jul 12 00:38:00 2012 -0700
     8.3 @@ -29,6 +29,7 @@
     8.4      Barriered<FixedArray> functions_;
     8.5      Barriered<FixedArray> publics_;
     8.6      Barriered<FixedArray> natives_;
     8.7 +    Barriered<String> file_;
     8.8      void *nativeIdentity_;
     8.9  
    8.10    public:
    8.11 @@ -49,6 +50,9 @@
    8.12      FixedArray *natives() {
    8.13          return natives_;
    8.14      }
    8.15 +    String *file() {
    8.16 +        return file_;
    8.17 +    }
    8.18  
    8.19      void setPublics(Handle<FixedArray> publics) {
    8.20          publics_ = publics;
    8.21 @@ -56,6 +60,9 @@
    8.22      void setNatives(Handle<FixedArray> natives) {
    8.23          natives_ = natives;
    8.24      }
    8.25 +    void setPath(Handle<String> path) {
    8.26 +        file_ = path;
    8.27 +    }
    8.28  
    8.29      void *nativeIdentity() {
    8.30          return nativeIdentity_;
    8.31 @@ -74,6 +81,9 @@
    8.32      static inline size_t offsetOfNatives() {
    8.33          return offsetof(Module, natives_);
    8.34      }
    8.35 +    static inline size_t offsetOfFile() {
    8.36 +        return offsetof(Module, file_);
    8.37 +    }
    8.38      // End GC Descriptor.
    8.39  
    8.40      static inline Module *cast(Object *obj) {
     9.1 --- a/jitcraft/ObjectVisitor.h	Wed Jul 11 01:12:54 2012 -0700
     9.2 +++ b/jitcraft/ObjectVisitor.h	Thu Jul 12 00:38:00 2012 -0700
     9.3 @@ -68,6 +68,7 @@
     9.4          visitField(obj, Code::offsetOfLocals());
     9.5          visitField(obj, Code::offsetOfObjects());
     9.6          visitField(obj, Code::offsetOfSafepoints());
     9.7 +        visitField(obj, Code::offsetOfSourceMap());
     9.8          return sizeof(Code);
     9.9      }
    9.10  
    9.11 @@ -80,6 +81,7 @@
    9.12          visitField(obj, Module::offsetOfFunctions());
    9.13          visitField(obj, Module::offsetOfPublics());
    9.14          visitField(obj, Module::offsetOfNatives());
    9.15 +        visitField(obj, Module::offsetOfFile());
    9.16          return sizeof(Module);
    9.17      }
    9.18  
    10.1 --- a/jitcraft/Opcodes.cpp	Wed Jul 11 01:12:54 2012 -0700
    10.2 +++ b/jitcraft/Opcodes.cpp	Thu Jul 12 00:38:00 2012 -0700
    10.3 @@ -23,6 +23,7 @@
    10.4  #include "Zone.h"
    10.5  #include "Array.h"
    10.6  #include "Strings.h"
    10.7 +#include "CompactBuffer.h"
    10.8  #include "Heap-inl.h"
    10.9  
   10.10  using namespace ke;
   10.11 @@ -38,7 +39,8 @@
   10.12  Code *
   10.13  Code::New(Zone *zone, Handle<ByteArray> bytecode, Handle<FixedArray> locals,
   10.14            Handle<FixedArray> objects, unsigned maxStackDepth, Handle<Module> module,
   10.15 -	  Handle<ByteArray> safepoints)
   10.16 +	      Handle<ByteArray> safepoints, Handle<ByteArray> sourcemap,
   10.17 +          unsigned lineNumber)
   10.18  {
   10.19      Local<Code> code(zone, Code::cast(zone->allocate(MapKind_Code, sizeof(Code), Heap::Tenure_Old)));
   10.20      if (!code)
   10.21 @@ -50,6 +52,8 @@
   10.22      code->maxStackDepth_ = maxStackDepth;
   10.23      code->module_ = module;
   10.24      code->safepoints_ = safepoints;
   10.25 +    code->sourcemap_ = sourcemap;
   10.26 +    code->lineNumber_ = lineNumber;
   10.27      return code;
   10.28  }
   10.29  
   10.30 @@ -98,6 +102,28 @@
   10.31      return Address(result) + sizeof(unsigned);
   10.32  }
   10.33  
   10.34 +SourcePosition
   10.35 +Code::pcToSource(unsigned pc)
   10.36 +{
   10.37 +    assert(pc < bytecode_->length());
   10.38 +
   10.39 +    CompactBufferReader reader(sourcemap_->raw(), sourcemap_->raw() + sourcemap_->length());
   10.40 +
   10.41 +    unsigned line = 1;
   10.42 +    unsigned col = 0;
   10.43 +    unsigned curPc = 0;
   10.44 +    while (!reader.done()) {
   10.45 +        curPc += reader.readUint32();
   10.46 +        if (curPc > pc)
   10.47 +            break;
   10.48 +
   10.49 +        line = reader.readUint32();
   10.50 +        col = reader.readUint32();
   10.51 +    }
   10.52 +
   10.53 +    return SourcePosition(lineNumber_ + line, col);
   10.54 +}
   10.55 +
   10.56  // All jumps must be the same length.
   10.57  STATIC_ASSERT(OP_JL_LENGTH == OP_JUMP_LENGTH);
   10.58  STATIC_ASSERT(OP_JLE_LENGTH == OP_JUMP_LENGTH);
    11.1 --- a/jitcraft/Stack.cpp	Wed Jul 11 01:12:54 2012 -0700
    11.2 +++ b/jitcraft/Stack.cpp	Thu Jul 12 00:38:00 2012 -0700
    11.3 @@ -20,8 +20,9 @@
    11.4  #include <stdlib.h>
    11.5  #include "Stack.h"
    11.6  #include "Zone.h"
    11.7 +#include "Strings.h"
    11.8 +#include "Modules.h"
    11.9  #include "Heap-inl.h"
   11.10 -#include "Strings.h"
   11.11  
   11.12  using namespace ke;
   11.13  
   11.14 @@ -245,42 +246,50 @@
   11.15      return false;
   11.16  }
   11.17  
   11.18 -StackIter::StackIter(Zone *zone)
   11.19 -  : pc_(zone->stack().top()->pc),
   11.20 -    fp_(zone->stack().top()->fp)
   11.21 -{
   11.22 -}
   11.23 -
   11.24 -bool
   11.25 -StackIter::done() const
   11.26 -{
   11.27 -    return !fp_;
   11.28 -}
   11.29 -
   11.30 -const char *
   11.31 -StackIter::function() const
   11.32 -{
   11.33 -    if (fp_->isNative())
   11.34 -        return fp_->native()->name()->chars();
   11.35 -    if (Function *fun = fp_->maybeFun())
   11.36 -        return fun->name()->chars();
   11.37 -    return "<toplevel>";
   11.38 -}
   11.39 -
   11.40 -unsigned
   11.41 -StackIter::lineNumber() const
   11.42 -{
   11.43 -    return 0;
   11.44 -}
   11.45 -
   11.46 -const char *
   11.47 -StackIter::source() const
   11.48 -{
   11.49 -    if (fp_->isNative())
   11.50 -        return "<native>";
   11.51 -    return "unknown";
   11.52 -}
   11.53 -
   11.54 +StackIter::StackIter(Zone *zone)
   11.55 +  : pc_(zone->stack().top()->pc),
   11.56 +    fp_(zone->stack().top()->fp)
   11.57 +{
   11.58 +}
   11.59 +
   11.60 +bool
   11.61 +StackIter::done() const
   11.62 +{
   11.63 +    return !fp_;
   11.64 +}
   11.65 +
   11.66 +const char *
   11.67 +StackIter::function() const
   11.68 +{
   11.69 +    if (fp_->isNative())
   11.70 +        return fp_->native()->name()->chars();
   11.71 +    if (Function *fun = fp_->maybeFun())
   11.72 +        return fun->name()->chars();
   11.73 +    return "<toplevel>";
   11.74 +}
   11.75 +
   11.76 +unsigned
   11.77 +StackIter::lineNumber() const
   11.78 +{
   11.79 +    if (fp_->isNative())
   11.80 +        return 0;
   11.81 +    if (fp_->maybeFun()) {
   11.82 +        unsigned offs = fp_->code()->pcToOffset(pc_);
   11.83 +        return fp_->code()->pcToSource(offs).line;
   11.84 +    }
   11.85 +    return fp_->code()->lineNumber();
   11.86 +}
   11.87 +
   11.88 +const char *
   11.89 +StackIter::source() const
   11.90 +{
   11.91 +    if (fp_->isNative())
   11.92 +        return "<native>";
   11.93 +    return fp_->code()->module()->file()
   11.94 +           ? fp_->code()->module()->file()->chars()
   11.95 +           : "(anonymous)";
   11.96 +}
   11.97 +
   11.98  void
   11.99  StackIter::prev()
  11.100  {
    12.1 --- a/jitcraft/Token.h	Wed Jul 11 01:12:54 2012 -0700
    12.2 +++ b/jitcraft/Token.h	Thu Jul 12 00:38:00 2012 -0700
    12.3 @@ -30,6 +30,12 @@
    12.4          col(-1)
    12.5      {
    12.6      }
    12.7 +
    12.8 +    SourcePosition(unsigned line, unsigned col)
    12.9 +      : line(line),
   12.10 +        col(col)
   12.11 +    {
   12.12 +    }
   12.13  };
   12.14  
   12.15  // List of tokens the scanner can recognize.
    13.1 --- a/jitcraft/Vector.h	Wed Jul 11 01:12:54 2012 -0700
    13.2 +++ b/jitcraft/Vector.h	Thu Jul 12 00:38:00 2012 -0700
    13.3 @@ -73,6 +73,10 @@
    13.4          nitems = 0;
    13.5      }
    13.6  
    13.7 +    T *buffer() const {
    13.8 +        return data;
    13.9 +    }
   13.10 +
   13.11    private:
   13.12      bool GrowIfNeeded(size_t needed)
   13.13      {
    14.1 --- a/jitcraft/jitcraft.vcxproj	Wed Jul 11 01:12:54 2012 -0700
    14.2 +++ b/jitcraft/jitcraft.vcxproj	Thu Jul 12 00:38:00 2012 -0700
    14.3 @@ -134,6 +134,7 @@
    14.4      <ClInclude Include="Barriers.h" />
    14.5      <ClInclude Include="BytecodeEmitter.h" />
    14.6      <ClInclude Include="BytecodeCompiler.h" />
    14.7 +    <ClInclude Include="CompactBuffer.h" />
    14.8      <ClInclude Include="CompileContext.h" />
    14.9      <ClInclude Include="FixedArray.h" />
   14.10      <ClInclude Include="Functions.h" />