Class: Twostroke::Runtime::Types::Function

Inherits:
Object
  • Object
show all
Defined in:
lib/twostroke/runtime/types/function.rb

Instance Attribute Summary collapse

Attributes inherited from Object

#_class, #data, #extensible

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Object

#can_put, #construct, #constructing?, #default_value, #define_own_property, #delete, #delete!, #each_enumerable_property, #generic_items, #get, #get_own_property, #get_property, #has_accessor, #has_own_property, #has_property, #proto_put, #put, set_global_prototype

Constructor Details

#initialize(function, source, name, arguments) ⇒ Function

Returns a new instance of Function.



36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/twostroke/runtime/types/function.rb', line 36

def initialize(function, source, name, arguments)
  @function = function
  @source = source
  @name = name
  @arguments = arguments
  # setting @_class to Function's constructor would result in a stack overflow,
  # so we'll set it to nil and patch things up after @@constructor_function has
  # been set
  @_class = nil unless defined?(@@constructor_function)
  super()
  @prototype = nil
  proto_put "prototype", Object.new
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def arguments
  @arguments
end

#functionObject (readonly)

Returns the value of attribute function.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def function
  @function
end

#nameObject (readonly)

Returns the value of attribute name.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def name
  @name
end

#sourceObject (readonly)

Returns the value of attribute source.



35
36
37
# File 'lib/twostroke/runtime/types/function.rb', line 35

def source
  @source
end

Class Method Details

.constructor_functionObject



3
4
5
6
7
8
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
# File 'lib/twostroke/runtime/types/function.rb', line 3

def self.constructor_function
  unless defined?(@@constructor_function)
    @@constructor_function = nil # lock the Function constructor out from here...
    @@created_funcs = 0
    @@constructor_function = Function.new(->(scope, this, args) {
      formal_parameters = (args.size > 1 ? args[0...-1] : []).map { |a| Twostroke::Runtime::Types.to_string(a).string }
      src = Twostroke::Runtime::Types.to_string(args[-1] || Undefined.new).string
      
      parser = Twostroke::Parser.new(Twostroke::Lexer.new(src))
      parser.parse

      @@created_funcs += 1
      fun_ast = Twostroke::AST::Function.new name: "anonymous", arguments: formal_parameters, statements: parser.statements
      compiler = Twostroke::Compiler::TSASM.new [fun_ast], "runtime_created_#{@@created_funcs}_"
      compiler.compile
      
      vm = scope.global_scope.vm
      compiler.bytecode.each do |k,v|
        vm.bytecode[k] = v
      end
      
      global_scope = vm.global_scope
      fun = Function.new(->(_scope, _this, _args) {
        Twostroke::Runtime::VM::Frame.new(vm, :"runtime_created_#{@@created_funcs}_fn_1", fun).execute(global_scope, _this, _args)
      }, src, "anonymous", formal_parameters)
    }, nil, "Function", [])
    @@constructor_function.proto_put "constructor", @@constructor_function
    @@constructor_function._class = @@constructor_function
  end
  @@constructor_function
end

Instance Method Details

#call(upper_scope, this, args) ⇒ Object



73
74
75
76
77
78
79
80
81
# File 'lib/twostroke/runtime/types/function.rb', line 73

def call(upper_scope, this, args)
  retn_val = function.(upper_scope, this || upper_scope.global_scope.root_object, args)
  # prevent non-Value objects being returned to javascript
  if retn_val.is_a? Value
    retn_val
  else
    Undefined.new
  end
end

#has_instance(obj) ⇒ Object



54
55
56
57
58
59
60
61
62
63
# File 'lib/twostroke/runtime/types/function.rb', line 54

def has_instance(obj)
  return false unless obj.is_a? Object
  o = get "prototype"
  Twostroke::Runtime::Lib.throw_type_error "Function prototype not an object" unless o.is_a? Object
  loop do
    obj = obj.prototype
    return false unless obj.is_a?(Object)
    return true if obj == o
  end
end

#primitive_valueObject



69
70
71
# File 'lib/twostroke/runtime/types/function.rb', line 69

def primitive_value
  String.new "function #{name}(#{arguments.join ","}) { #{source || "[native code]"} }"
end

#prototypeObject



50
51
52
# File 'lib/twostroke/runtime/types/function.rb', line 50

def prototype
  @prototype ||= Function.constructor_function.get("prototype")
end

#typeofObject



65
66
67
# File 'lib/twostroke/runtime/types/function.rb', line 65

def typeof
  "function"
end