예제 #1
0
  void test_specialize_transforms_ivars_to_slots() {
    CompiledMethod* cm = CompiledMethod::create(state);
    Tuple* tup = Tuple::from(state, 1, state->symbol("@blah"));
    cm->literals(state, tup);

    InstructionSequence* iseq = InstructionSequence::create(state, 3);
    iseq->opcodes()->put(state, 0, Fixnum::from(InstructionSequence::insn_push_ivar));
    iseq->opcodes()->put(state, 1, Fixnum::from(0));
    iseq->opcodes()->put(state, 2, Fixnum::from(InstructionSequence::insn_push_nil));

    cm->iseq(state, iseq);

    VMMethod* vmm = new VMMethod(state, cm);

    Object::Info ti(ObjectType);
    ti.slots[state->symbol("@blah")->index()] = 5;
    ti.slot_locations.resize(6);
    ti.slot_locations[5] = 33;
    vmm->specialize(state, cm, &ti);

    TS_ASSERT_EQUALS(vmm->total, 3U);
    TS_ASSERT_EQUALS(vmm->opcodes[0], static_cast<unsigned int>(InstructionSequence::insn_push_my_offset));
    TS_ASSERT_EQUALS(vmm->opcodes[1], 33U);
    TS_ASSERT_EQUALS(vmm->opcodes[2], static_cast<unsigned int>(InstructionSequence::insn_push_nil));
  }
예제 #2
0
  void test_set_breakpoint_flags() {
    CompiledMethod* cm = CompiledMethod::create(state);
    Tuple* tup = Tuple::from(state, 1, state->symbol("@blah"));
    cm->literals(state, tup);

    InstructionSequence* iseq = InstructionSequence::create(state, 3);
    iseq->opcodes()->put(state, 0, Fixnum::from(InstructionSequence::insn_push_ivar));
    iseq->opcodes()->put(state, 1, Fixnum::from(0));
    iseq->opcodes()->put(state, 2, Fixnum::from(InstructionSequence::insn_push_nil));

    cm->iseq(state, iseq);

    VMMethod* vmm = new VMMethod(state, cm);

    vmm->set_breakpoint_flags(state, 0, 1 << 24);
    TS_ASSERT_EQUALS(vmm->opcodes[0], (1U << 24) | static_cast<unsigned int>(InstructionSequence::insn_push_ivar));

    vmm->set_breakpoint_flags(state, 0, 7 << 24);
    TS_ASSERT_EQUALS(vmm->opcodes[0], (7U << 24) | static_cast<unsigned int>(InstructionSequence::insn_push_ivar));

    vmm->set_breakpoint_flags(state, 0, 0);
    TS_ASSERT_EQUALS(vmm->opcodes[0], static_cast<unsigned int>(InstructionSequence::insn_push_ivar));

    vmm->set_breakpoint_flags(state, 1, 1);
    TS_ASSERT_EQUALS(vmm->opcodes[1], 0U);
  }
예제 #3
0
  void test_iseq() {
    mar->sstream.str(std::string("i\n1\n0\n"));

    Object* obj = mar->unmarshal();

    TS_ASSERT(kind_of<InstructionSequence>(obj));

    InstructionSequence* seq = as<InstructionSequence>(obj);

    TS_ASSERT(kind_of<Tuple>(seq->opcodes()));

    TS_ASSERT_EQUALS(seq->opcodes()->num_fields(), 1);

    TS_ASSERT_EQUALS(seq->opcodes()->at(state, 0), Fixnum::from(0));
  }
예제 #4
0
  void InstructionSequence::Info::show(STATE, Object* self, int level) {
    InstructionSequence* iseq = as<InstructionSequence>(self);

    class_header(state, self);
    indent_attribute(++level, "opcodes"); iseq->opcodes()->show(state, level);
    close_body(level);
  }
예제 #5
0
  InstructionSequence* InstructionSequence::create(STATE, size_t instructions) {
    InstructionSequence* is = InstructionSequence::allocate(state, G(iseq));

    is->opcodes(state, Tuple::create(state, instructions));

    return is;
  }
예제 #6
0
  void test_iseq() {
    InstructionSequence* iseq = InstructionSequence::create(state, 1);
    iseq->opcodes()->put(state, 0, Fixnum::from(0));

    mar->marshal(iseq);
    TS_ASSERT_EQUALS(mar->sstream.str(), std::string("i\n1\n0\n"));
  }
예제 #7
0
  void test_validate_ip() {
    CompiledMethod* cm = CompiledMethod::create(state);
    Tuple* tup = Tuple::from(state, 1, state->symbol("@blah"));
    cm->literals(state, tup);

    InstructionSequence* iseq = InstructionSequence::create(state, 3);
    iseq->opcodes()->put(state, 0, Fixnum::from(InstructionSequence::insn_push_ivar));
    iseq->opcodes()->put(state, 1, Fixnum::from(0));
    iseq->opcodes()->put(state, 2, Fixnum::from(InstructionSequence::insn_push_nil));

    cm->iseq(state, iseq);

    VMMethod* vmm = new VMMethod(state, cm);
    TS_ASSERT_EQUALS(vmm->validate_ip(state, 0), true);
    TS_ASSERT_EQUALS(vmm->validate_ip(state, 1), false);
    TS_ASSERT_EQUALS(vmm->validate_ip(state, 2), true);
  }
예제 #8
0
    void test_validate_ip() {
        CompiledCode* code = CompiledCode::create(state);
        Tuple* tup = Tuple::from(state, 1, state->symbol("@blah"));
        code->literals(state, tup);

        InstructionSequence* iseq = InstructionSequence::create(state, 3);
        iseq->opcodes()->put(state, 0, Fixnum::from(InstructionSequence::insn_push_ivar));
        iseq->opcodes()->put(state, 1, Fixnum::from(0));
        iseq->opcodes()->put(state, 2, Fixnum::from(InstructionSequence::insn_push_nil));

        code->iseq(state, iseq);

        MachineCode* mcode = new MachineCode(state, code);
        TS_ASSERT_EQUALS(mcode->validate_ip(state, 0), true);
        TS_ASSERT_EQUALS(mcode->validate_ip(state, 1), false);
        TS_ASSERT_EQUALS(mcode->validate_ip(state, 2), true);
    }
예제 #9
0
  void test_get_breakpoint_flags() {
    CompiledMethod* cm = CompiledMethod::create(state);
    Tuple* tup = Tuple::from(state, 1, state->symbol("@blah"));
    cm->literals(state, tup);

    InstructionSequence* iseq = InstructionSequence::create(state, 3);
    iseq->opcodes()->put(state, 0, Fixnum::from(InstructionSequence::insn_push_ivar));
    iseq->opcodes()->put(state, 1, Fixnum::from(0));
    iseq->opcodes()->put(state, 2, Fixnum::from(4 << 24 | InstructionSequence::insn_push_nil));

    cm->iseq(state, iseq);

    VMMethod* vmm = new VMMethod(state, cm);

    TS_ASSERT_EQUALS(vmm->get_breakpoint_flags(state, 0), 0U);
    TS_ASSERT_EQUALS(vmm->get_breakpoint_flags(state, 2), (4U << 24));
    TS_ASSERT_EQUALS(vmm->get_breakpoint_flags(state, 1), 0U);
  }
예제 #10
0
  void test_create() {
    CompiledMethod* cm = CompiledMethod::create(state);
    Tuple* tup = Tuple::from(state, 1, state->symbol("blah"));
    cm->literals(state, tup);

    InstructionSequence* iseq = InstructionSequence::create(state, 1);
    iseq->opcodes()->put(state, 0, Fixnum::from(0));

    cm->iseq(state, iseq);

    VMMethod* vmm = new VMMethod(state, cm);

    TS_ASSERT_EQUALS(vmm->total, 1U);
    TS_ASSERT_EQUALS(vmm->opcodes[0], 0U);
  }
예제 #11
0
    void test_create() {
        CompiledCode* code = CompiledCode::create(state);
        Tuple* tup = Tuple::from(state, 1, state->symbol("blah"));
        code->literals(state, tup);

        InstructionSequence* iseq = InstructionSequence::create(state, 1);
        iseq->opcodes()->put(state, 0, Fixnum::from(0));

        code->iseq(state, iseq);

        MachineCode* mcode = new MachineCode(state, code);

        TS_ASSERT_EQUALS(mcode->total, 1U);
        TS_ASSERT_EQUALS(mcode->opcodes[0], 0U);
    }
예제 #12
0
  InstructionSequence* UnMarshaller::get_iseq() {
    size_t count;
    long op;
    stream >> count;

    InstructionSequence* iseq = InstructionSequence::create(state, count);
    Tuple* ops = iseq->opcodes();

    for(size_t i = 0; i < count; i++) {
      stream >> op;
      ops->put(state, i, Fixnum::from(op));
    }

    iseq->post_marshal(state);

    return iseq;
  }
예제 #13
0
파일: marshal.cpp 프로젝트: Emily/rubinius
  InstructionSequence* UnMarshaller::get_iseq() {
    size_t count;
    char data[OPCODE_LENGTH];
    stream >> count;

    // Read off newline
    stream.get();

    InstructionSequence* iseq = InstructionSequence::create(state, count);
    Tuple* ops = iseq->opcodes();

    for(size_t i = 0; i < count; i++) {
      stream.getline(data, OPCODE_LENGTH);
      long op = strtol(data, NULL, 10);
      ops->put(state, i, Fixnum::from(op));
    }

    iseq->post_marshal(state);

    return iseq;
  }
예제 #14
0
파일: iseq.cpp 프로젝트: dbalatero/rubinius
 InstructionSequence* InstructionSequence::create(STATE, size_t instructions) {
   InstructionSequence* is = state->new_object<InstructionSequence>(G(iseq));
   is->opcodes(state, Tuple::create(state, instructions));
   return is;
 }
예제 #15
0
  bool BytecodeVerification::verify(STATE) {
    // Do this setup here instead of the constructor so we can do
    // some validation of the CompiledCode's fields we read them.

    // Double check the method itself, since it might be a nil
    if(!kind_of<CompiledCode>(method_)) {
      fail("invalid method", -1);
      return false;
    }

    if(Fixnum* fix = try_as<Fixnum>(method_->local_count())) {
      locals_ = fix->to_native();
    } else {
      fail("method not initialized properly", -1);
      return false;
    }

    InstructionSequence* iseq = try_as<InstructionSequence>(method_->iseq());
    if(!iseq) {
      fail("method not initialized properly", -1);
      return false;
    }

    if(Tuple* tup = try_as<Tuple>(iseq->opcodes())) {
      ops_ = tup;
    } else {
      fail("method not initialized properly", -1);
      return false;
    }

    if(Fixnum* fix = try_as<Fixnum>(method_->stack_size())) {
      max_stack_allowed_ = fix->to_native();
    } else {
      fail("method not initialized properly", -1);
      return false;
    }

    if(Fixnum* fix = try_as<Fixnum>(method_->splat())) {
      if(fix->to_native() >= locals_) {
        fail("invalid splat position", -1);
        return false;
      }
    }

    Fixnum* tot = try_as<Fixnum>(method_->total_args());
    Fixnum* req = try_as<Fixnum>(method_->required_args());
    Fixnum* post = try_as<Fixnum>(method_->post_args());

    if(!tot || !req || !post) {
      fail("method not initialized properly (missing arg counts)", -1);
      return false;
    }

    if(tot->to_native() > locals_) {
      fail("more arguments than local slots", -1);
      return false;
    }

    if(req->to_native() > tot->to_native()) {
      fail("more required arguments than total", -1);
      return false;
    }

    if(post->to_native() > req->to_native()) {
      fail("more post arguments than required", -1);
      return false;
    }

    if(post->to_native() > tot->to_native()) {
      fail("more post arguments than total", -1);
      return false;
    }

    total_ = ops_->num_fields();
    stack_ = new int32_t[total_];

    for(native_int i = 0; i < total_; i++) {
      stack_[i] = -1;
    }

    std::list<Section> ips;
    ips.push_back(Section(0, 0));

    while(!ips.empty()) {
      Section& section = ips.front();

      int ip = section.ip;
      int sp = section.sp;

      ips.pop_front();

      if(!verify_from(state, sp, ip, ips)) return false;
    }

    // Now, check there is a enough space for the stack locals.
    if(max_stack_seen_ + max_stack_local_ >= max_stack_allowed_) {
      fail("not enough space for stack locals", -1);
      return false;
    }

    return true;
  }