fn postprocess_parse_raw_code(&mut self) {
    // Dirty swap to take raw_code out of self and give it to the binary reader
    let mut raw_code: Vec<u8> = Vec::new();
    mem::swap(&mut self.raw.code, &mut raw_code);

    //
    // Estimate code size and preallocate the code storage
    // TODO: This step is not efficient and does double parse of all args
    //
    let mut r = BinaryReader::from_bytes(raw_code);

    let code_size = {
      let mut s = 0usize;
      while !r.eof() {
        let op: opcode::RawOpcode = r.read_u8();
        let arity = gen_op::opcode_arity(op) as usize;
        for _i in 0..arity {
          let _arg0 = compact_term::read(&mut r).unwrap();
        }
        s += arity + 1;
      }
      s
    };
    self.code.reserve(code_size);

    let debug_code_start = self.code.as_ptr();
    //println!("Code_size {} code_start {:p}", code_size, debug_code_start);

    //
    // Writing code unpacked to words here. Break at every new function_info.
    //
    r.reset();
    while !r.eof() {
      // Read the opcode from the code section
      let op: opcode::RawOpcode = r.read_u8();

      // Read `arity` args, and convert them to reasonable runtime values
      let arity = gen_op::opcode_arity(op);
      let mut args: Vec<FTerm> = Vec::new();
      for _i in 0..arity {
        let arg0 = compact_term::read(&mut r).unwrap();
        // Atom_ args now can be converted to Atom (VM atoms)
        let arg1 = match self.resolve_loadtime_values(&arg0) {
          Some(tmp) => tmp,
          None => arg0
        };
        args.push(arg1);
      }

      match op {
        // add nothing for label, but record its location
        x if x == gen_op::OPCODE_LABEL => {
          if let FTerm::SmallInt(f) = args[0] {
            // Store weak ptr to function and code offset to this label
            let floc = self.code.len();
            self.labels.insert(LabelId(f as Word),
                               CodeOffset(floc));
          } else {
            op_badarg_panic(op, &args, 0);
          }
        }

        // add nothing for line, but TODO: Record line contents
        x if x == gen_op::OPCODE_LINE => {}

        // else push the op and convert all args to LTerms, also remember
        // code offsets for label values
        _ => {
          if op == gen_op::OPCODE_FUNC_INFO {
            // arg[0] mod name, arg[1] fun name, arg[2] arity
            let funarity = FunArity {
              f: args[1].to_lterm(&mut self.lit_heap),
              arity: args[2].loadtime_word() as Arity
            };

            // Function code begins after the func_info opcode (1+3)
            let fun_begin = self.code.len() + 4;
            match self.mod_id {
              Some(_mod_id) => {
                self.funs.insert(funarity, fun_begin);
                ()
              },
              None => panic!("{}mod_id must be set at this point", module()),
            }
          }

          self.code.push(opcode::to_memory_word(op));
          self.store_opcode_args(&args);
        } // case _
      } // match op
    } // while !r.eof

    assert_eq!(debug_code_start, self.code.as_ptr(),
               "{}Must do no reallocations", module())
  }
/// Assume that loader raw structures are completed, and atoms are already
/// transferred to the VM, we can now parse opcodes and their args.
/// 'drained_code' is 'raw_code' moved out of 'self'
Assume that loader raw structures are completed, and atoms are already
transferred to the VM, we can now parse opcodes and their args.
Assume that loader raw structures are completed and atoms are already transferred to the VM we can now parse opcodes and their args .
fn postprocess_parse_raw_code(&mut self) {
    // Dirty swap to take raw_code out of self and give it to the binary reader
    let mut raw_code: Vec<u8> = Vec::new();
    mem::swap(&mut self.raw.code, &mut raw_code);
    //
    // Estimate code size and preallocate the code storage
    // TODO: This step is not efficient and does double parse of all args
    //
    let mut r = BinaryReader::from_bytes(raw_code);
    let code_size = {
      let mut s = 0usize;
      while !r.eof() {
        let op: opcode::RawOpcode = r.read_u8();
        let arity = gen_op::opcode_arity(op) as usize;
        for _i in 0..arity {
          let _arg0 = compact_term::read(&mut r).unwrap();
        }
        s += arity + 1;
      }
      s
    };
    self.code.reserve(code_size);
    let debug_code_start = self.code.as_ptr();
    //println!("Code_size {} code_start {:p}", code_size, debug_code_start);
    //
    // Writing code unpacked to words here. Break at every new function_info.
    //
    r.reset();
    while !r.eof() {
      // Read the opcode from the code section
      let op: opcode::RawOpcode = r.read_u8();
      // Read `arity` args, and convert them to reasonable runtime values
      let arity = gen_op::opcode_arity(op);
      let mut args: Vec<FTerm> = Vec::new();
      for _i in 0..arity {
        let arg0 = compact_term::read(&mut r).unwrap();
        // Atom_ args now can be converted to Atom (VM atoms)
        let arg1 = match self.resolve_loadtime_values(&arg0) {
          Some(tmp) => tmp,
          None => arg0
        };
        args.push(arg1);
      }
      match op {
        // add nothing for label, but record its location
        x if x == gen_op::OPCODE_LABEL => {
          if let FTerm::SmallInt(f) = args[0] {
            // Store weak ptr to function and code offset to this label
            let floc = self.code.len();
            self.labels.insert(LabelId(f as Word),
                               CodeOffset(floc));
          } else {
            op_badarg_panic(op, &args, 0);
          }
        }
        // add nothing for line, but TODO: Record line contents
        x if x == gen_op::OPCODE_LINE => {}
        // else push the op and convert all args to LTerms, also remember
        // code offsets for label values
        _ => {
          if op == gen_op::OPCODE_FUNC_INFO {
            // arg[0] mod name, arg[1] fun name, arg[2] arity
            let funarity = FunArity {
              f: args[1].to_lterm(&mut self.lit_heap),
              arity: args[2].loadtime_word() as Arity
            };
            // Function code begins after the func_info opcode (1+3)
            let fun_begin = self.code.len() + 4;
            match self.mod_id {
              Some(_mod_id) => {
                self.funs.insert(funarity, fun_begin);
                ()
              },
              None => panic!("{}mod_id must be set at this point", module()),
            }
          }
          self.code.push(opcode::to_memory_word(op));
          self.store_opcode_args(&args);
        } // case _
      } // match op
    } // while !r.eof
    assert_eq!(debug_code_start, self.code.as_ptr(),
               "{}Must do no reallocations", module())
  }
fn postprocess_parse_raw_code ( & mut self ) { // Dirty swap to take raw_code out of self and give it to the binary reader let mut raw_code : Vec < u8 > = Vec :: new ( ) ; mem :: swap ( & mut self . raw . code , & mut raw_code ) ; // // Estimate code size and preallocate the code storage // TODO: This step is not efficient and does double parse of all args // let mut r = BinaryReader :: from_bytes ( raw_code ) ; let code_size = { let mut s = 0usize ; while ! r . eof ( ) { let op : opcode :: RawOpcode = r . read_u8 ( ) ; let arity = gen_op :: opcode_arity ( op ) as usize ; for _i in 0 .. arity { let _arg0 = compact_term :: read ( & mut r ) . unwrap ( ) ; } s += arity + 1 ; } s } ; self . code . reserve ( code_size ) ; let debug_code_start = self . code . as_ptr ( ) ; //println!("Code_size {} code_start {:p}", code_size, debug_code_start); // // Writing code unpacked to words here. Break at every new function_info. // r . reset ( ) ; while ! r . eof ( ) { // Read the opcode from the code section let op : opcode :: RawOpcode = r . read_u8 ( ) ; // Read `arity` args, and convert them to reasonable runtime values let arity = gen_op :: opcode_arity ( op ) ; let mut args : Vec < FTerm > = Vec :: new ( ) ; for _i in 0 .. arity { let arg0 = compact_term :: read ( & mut r ) . unwrap ( ) ; // Atom_ args now can be converted to Atom (VM atoms) let arg1 = match self . resolve_loadtime_values ( & arg0 ) { Some ( tmp ) => tmp , None => arg0 } ; args . push ( arg1 ) ; } match op { // add nothing for label, but record its location x if x == gen_op :: OPCODE_LABEL => { if let FTerm :: SmallInt ( f ) = args [ 0 ] { // Store weak ptr to function and code offset to this label let floc = self . code . len ( ) ; self . labels . insert ( LabelId ( f as Word ) , CodeOffset ( floc ) ) ; } else { op_badarg_panic ( op , & args , 0 ) ; } } // add nothing for line, but TODO: Record line contents x if x == gen_op :: OPCODE_LINE => { } // else push the op and convert all args to LTerms, also remember // code offsets for label values _ => { if op == gen_op :: OPCODE_FUNC_INFO { // arg[0] mod name, arg[1] fun name, arg[2] arity let funarity = FunArity { f : args [ 1 ] . to_lterm ( & mut self . lit_heap ) , arity : args [ 2 ] . loadtime_word ( ) as Arity } ; // Function code begins after the func_info opcode (1+3) let fun_begin = self . code . len ( ) + 4 ; match self . mod_id { Some ( _mod_id ) => { self . funs . insert ( funarity , fun_begin ) ; ( ) } , None => panic ! ( " " module ( ) ) , } } self . code . push ( opcode :: to_memory_word ( op ) ) ; self . store_opcode_args ( & args ) ; } // case _ } // match op } // while !r.eof assert_eq ! ( debug_code_start self code as_ptr ( ) " " module ( ) ) }
Assume that loader raw structures are completed, and atoms are already
transferred to the VM, we can now parse opcodes and their args.
Assume that loader raw structures are completed and atoms are already transferred to the VM we can now parse opcodes and their args .
&mut self