Class: Erlang::ETF::NewFun

Inherits:
Object
  • Object
show all
Includes:
Term
Defined in:
lib/erlang/etf/new_fun.rb

Overview

1 4 1 16 4 4 N1 N2 N3 N4 N5
112 Size Arity Uniq Index NumFree Module Oldindex OldUniq Pid Free Vars

This is the new encoding of internal funs:

fun F/A and fun(Arg1,..) -> ... end.

Size

is the total number of bytes, including the Size field.

Arity

is the arity of the function implementing the fun.

Uniq

is the 16 bytes MD5 of the significant parts of the Beam file.

Index

is an index number. Each fun within a module has an unique index. Index is stored in big-endian byte order.

NumFree

is the number of free variables.

Module

is an encoded as an atom, using ATOM_EXT, SMALL_ATOM_EXT or ATOM_CACHE_REF. This is the module that the fun is implemented in.

OldIndex

is an integer encoded using SMALL_INTEGER_EXT or INTEGER_EXT. It is typically a small index into the module's fun table.

OldUniq

is an integer encoded using SMALL_INTEGER_EXT or INTEGER_EXT. Uniq is the hash value of the parse tree for the fun.

Pid

is a process identifier as in PID_EXT. It represents the process in which the fun was created.

Free vars

is NumFree number of terms, each one encoded according to its type.

(see NEW_FUN_EXT)

Constant Summary collapse

UINT8 =
Erlang::ETF::Term::UINT8
UINT32BE =
Erlang::ETF::Term::UINT32BE
UINT128BE =
Erlang::ETF::Term::UINT128BE
HEAD =
(UINT32BE + UINT8 + UINT128BE + UINT32BE + UINT32BE).freeze

Constants included from Term

Term::ATOM_CACHE_REF, Term::ATOM_EXT, Term::ATOM_INTERNAL_REF2, Term::ATOM_INTERNAL_REF3, Term::ATOM_UTF8_EXT, Term::BINARY_ENCODING, Term::BINARY_EXT, Term::BINARY_INTERNAL_REF, Term::BIT_BINARY_EXT, Term::BIT_BINARY_INTERNAL_REF, Term::COMPRESSED, Term::DIST_HEADER, Term::DOUBLE, Term::DOUBLEBE, Term::DOUBLELE, Term::ERLANG_MAGIC_BYTE, Term::EXPORT_EXT, Term::FLOAT_EXT, Term::FUN_EXT, Term::INT128, Term::INT128BE, Term::INT128LE, Term::INT16, Term::INT16BE, Term::INT16LE, Term::INT32, Term::INT32BE, Term::INT32LE, Term::INT64, Term::INT64BE, Term::INT64LE, Term::INT8, Term::INTEGER_EXT, Term::LARGE_BIG_EXT, Term::LARGE_TUPLE_EXT, Term::LIST_EXT, Term::MAP_EXT, Term::NEW_FLOAT_EXT, Term::NEW_FUN_EXT, Term::NEW_REFERENCE_EXT, Term::NIL_EXT, Term::PID_EXT, Term::PORT_EXT, Term::REFERENCE_EXT, Term::SINGLE, Term::SINGLEBE, Term::SINGLELE, Term::SMALL_ATOM_EXT, Term::SMALL_ATOM_UTF8_EXT, Term::SMALL_BIG_EXT, Term::SMALL_INTEGER_EXT, Term::SMALL_TUPLE_EXT, Term::STRING_EXT, Term::UINT128, Term::UINT128LE, Term::UINT16, Term::UINT16BE, Term::UINT16LE, Term::UINT32, Term::UINT32LE, Term::UINT64, Term::UINT64BE, Term::UINT64LE

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Term

#<=>, binary_encoding, #eql?, #erlang_external_type, #hash, included, #to_erlang_etf

Constructor Details

#initialize(term, arity = nil, uniq = nil, index = nil, mod = nil, old_index = nil, old_uniq = nil, pid = nil, free_vars = nil) ⇒ NewFun

Returns a new instance of NewFun.

Raises:

  • (ArgumentError)


88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/erlang/etf/new_fun.rb', line 88

def initialize(term, arity = nil, uniq = nil, index = nil, mod = nil, old_index = nil, old_uniq = nil, pid = nil, free_vars = nil)
  raise ArgumentError, "term must be of type Erlang::Function" if not term.kind_of?(Erlang::Function) or not term.new_function?
  @term      = term
  @arity     = arity
  @uniq      = uniq
  @index     = index
  @mod       = mod
  @old_index = old_index
  @old_uniq  = old_uniq
  @pid       = pid
  @free_vars = free_vars
end

Class Method Details

.[](term, arity = nil, uniq = nil, index = nil, mod = nil, old_index = nil, old_uniq = nil, pid = nil, free_vars = nil) ⇒ Object



71
72
73
# File 'lib/erlang/etf/new_fun.rb', line 71

def [](term, arity = nil, uniq = nil, index = nil, mod = nil, old_index = nil, old_uniq = nil, pid = nil, free_vars = nil)
  return new(term, arity, uniq, index, mod, old_index, old_uniq, pid, free_vars)
end

.erlang_load(buffer) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/erlang/etf/new_fun.rb', line 75

def erlang_load(buffer)
  _, arity, uniq_hi, uniq_lo, index, num_free = buffer.read(29).unpack(HEAD)
  uniq = (uniq_hi << 64) + uniq_lo
  mod       = Erlang::ETF.read_term(buffer)
  old_index = Erlang::ETF.read_term(buffer)
  old_uniq  = Erlang::ETF.read_term(buffer)
  pid       = Erlang::ETF.read_term(buffer)
  free_vars = Array.new(num_free); num_free.times { |i| free_vars[i] = Erlang::ETF.read_term(buffer) }
  term      = Erlang::Function[arity: Erlang.from(arity), uniq: Erlang.from(uniq), index: Erlang.from(index), mod: Erlang.from(mod), old_index: Erlang.from(old_index), old_uniq: Erlang.from(old_uniq), pid: Erlang.from(pid), free_vars: Erlang.from(free_vars)]
  return new(term, arity, uniq, index, mod, old_index, old_uniq, pid, free_vars)
end

Instance Method Details

#erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING)) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/erlang/etf/new_fun.rb', line 101

def erlang_dump(buffer = ::String.new.force_encoding(BINARY_ENCODING))
  buffer << NEW_FUN_EXT
  size      = 0
  arity     = @arity     || @term.arity
  uniq      = @uniq      || @term.uniq
  index     = @index     || @term.index
  free_vars = @free_vars || @term.free_vars
  num_free  = free_vars.length
  sizestart = buffer.bytesize
  buffer << [size, arity, uniq >> 64, uniq, index, num_free].pack(HEAD)
  Erlang::ETF.write_term(@mod       || @term.mod,       buffer)
  Erlang::ETF.write_term(@old_index || @term.old_index, buffer)
  Erlang::ETF.write_term(@old_uniq  || @term.old_uniq,  buffer)
  Erlang::ETF.write_term(@pid       || @term.pid,       buffer)
  num_free.times { |i| Erlang::ETF.write_term(free_vars[i], buffer) }
  sizeend   = buffer.bytesize
  size      = sizeend - sizestart
  buffer.setbyte(sizestart + 0, size >> 24)
  buffer.setbyte(sizestart + 1, size >> 16)
  buffer.setbyte(sizestart + 2, size >> 8)
  buffer.setbyte(sizestart + 3, size)
  return buffer
end

#inspectObject



125
126
127
128
129
130
131
# File 'lib/erlang/etf/new_fun.rb', line 125

def inspect
  if @arity.nil? and @uniq.nil? and @index.nil? and @mod.nil? and @old_index.nil? and @old_uniq.nil? and @pid.nil? and @free_vars.nil?
    return super
  else
    return "#{self.class}[#{@term.inspect}, #{@arity.inspect}, #{@uniq.inspect}, #{@index.inspect}, #{@mod.inspect}, #{@old_index.inspect}, #{@old_uniq.inspect}, #{@pid.inspect}, #{@free_vars.inspect}]"
  end
end

#pretty_print(pp) ⇒ Object



133
134
135
136
137
138
139
140
# File 'lib/erlang/etf/new_fun.rb', line 133

def pretty_print(pp)
  state = [@term]
  state.push(@arity, @uniq, @index, @mod, @old_index, @old_uniq, @pid, @free_vars) if not @arity.nil? or not @uniq.nil? or not @index.nil? or not @mod.nil? or not @old_index.nil? or not @old_uniq.nil? or not @pid.nil? or not @free_vars.nil?
  return pp.group(1, "#{self.class}[", "]") do
    pp.breakable ''
    pp.seplist(state) { |obj| obj.pretty_print(pp) }
  end
end