Class: RubyRunJs::JsFunction

Inherits:
JsBaseObject show all
Defined in:
lib/ruby_run_js/objects/js_function.rb

Instance Attribute Summary collapse

Attributes inherited from JsBaseObject

#_class, #extensible, #own, #prototype, #value

Instance Method Summary collapse

Methods inherited from JsBaseObject

#_type, #can_put, #default_value, #define_own_property, #delete, #get, #get_items, #get_own_property, #get_property, #has_property, #put, #set_items

Methods included from Helper

#check_object, #get_member, #get_member_dot, #is_accessor_descriptor, #is_callable, #is_data_descriptor, #is_generic_descriptor, #is_primitive, #make_error, #strict_equality

Methods included from ConversionHelper

#convert_to_js_type, #to_boolean, #to_int32, #to_integer, #to_number, #to_object, #to_primitive, #to_string, #to_uint16, #to_uint32

Constructor Details

#initialize(code, parent_scope, params, name, builtin, is_declaration, definitions, prototype = nil) ⇒ JsFunction

Returns a new instance of JsFunction.



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/ruby_run_js/objects/js_function.rb', line 9

def initialize( code, parent_scope, params, name, builtin, is_declaration, definitions, prototype = nil )
  super()
  @_class = 'Function'
  @prototype = prototype
  @code = code
  @builtin = builtin
  @parent_scope = parent_scope
  @params = params
  @name = name
  @is_declaration = is_declaration
  @definitions = definitions
  @is_native = code.is_a?(Proc) || code.is_a?(Method)

  unless name.nil? || name.empty?
    define_own_property('name',{
      'value' => name,
      'writable' => false,
      'enumerable' => false,
      'configurable' => true
    })
  end

  define_own_property('length',{
    'value' => params.nil? ? 0.0 : params.size.to_f,
    'writable' => true,
    'enumerable' => false,
    'configurable' => true
  })

  unless @is_native
    proto = builtin.new_object
    proto.define_own_property('constructor',{
      'value' => self,
      'writable' => true,
      'enumerable' => false,
      'configurable' => true
    })
    define_own_property('prototype',{
      'value' => proto,
      'writable' => true,
      'enumerable' => false,
      'configurable' => false
    })
  end
  
end

Instance Attribute Details

#codeObject (readonly)

Returns the value of attribute code.



7
8
9
# File 'lib/ruby_run_js/objects/js_function.rb', line 7

def code
  @code
end

#is_nativeObject (readonly)

Returns the value of attribute is_native.



7
8
9
# File 'lib/ruby_run_js/objects/js_function.rb', line 7

def is_native
  @is_native
end

#nameObject (readonly)

Returns the value of attribute name.



7
8
9
# File 'lib/ruby_run_js/objects/js_function.rb', line 7

def name
  @name
end

#paramsObject (readonly)

Returns the value of attribute params.



7
8
9
# File 'lib/ruby_run_js/objects/js_function.rb', line 7

def params
  @params
end

#parent_scopeObject (readonly)

Returns the value of attribute parent_scope.



7
8
9
# File 'lib/ruby_run_js/objects/js_function.rb', line 7

def parent_scope
  @parent_scope
end

Instance Method Details

#call(this, args = []) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/ruby_run_js/objects/js_function.rb', line 56

def call(this, args = [])
  if @is_native # native ruby function
    native_method = code
    params = native_method.parameters
    if params.empty?
      return native_method.call
    end
    js_args = [this] + args
    js_param_size = js_args.size
    native_param_size = params.size - 1
    last_is_rest = params[-1][0] == :rest

    native_params = [@builtin]
    if last_is_rest
      param_size = native_param_size - 1 > js_param_size ? native_param_size - 1 : js_param_size
      (0...param_size).each do |i|
        native_params.append(i < js_param_size ? js_args[i] : undefined)
      end
    else
      native_param_size.times do |i|
        native_params.append(i < js_param_size ? js_args[i] : undefined)
      end
    end
    return native_method.call(*native_params)
  else
    return @builtin.executor.call_js_func(self, this, args)
  end
end

#construct(args) ⇒ Object



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/ruby_run_js/objects/js_function.rb', line 103

def construct(args)
  native_constructor = get('__new__')
  if native_constructor != undefined
    return native_constructor.call(undefined, args)
  end
  proto = get('prototype')
  if proto.js_type != :Object
    proto = @builtin.object_prototype
  end
  obj = JsObject.new(proto)
  res = call(obj, args)
  if res.js_type == :Object
    return res
  end
  obj
end

#generate_my_scope(this, args) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/ruby_run_js/objects/js_function.rb', line 120

def generate_my_scope(this, args)
  scope = LocalScope.new(@parent_scope, @builtin)
  scope.create_bindings(@definitions)

  @params.length.times do |i|
    # params have been created
    scope.set_binding(@params[i], args[i])
  end
  scope.this_binding = this
  unless @params.include?('arguments')
    scope.own['arguments'] = @builtin.new_arguments_obj(args)
  end
  if !@is_declaration && @name != nil && @name != '' && !scope.own.key?(@name)
    scope.own[@name] = self
  end
  scope
end

#has_instance(other) ⇒ Object

Parameters:



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/ruby_run_js/objects/js_function.rb', line 86

def has_instance(other)
  return false if other.js_type != :Object
  o = get('prototype')
  if o.js_type != :Object
    raise make_error('TypeError','Function has non-object prototype in instanceof check')
  end
  loop do
    other = other.prototype
    unless other
      return false
    end
    if other == o
      return true
    end
  end
end