context.rb 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. require 'stringio'
  2. module V8
  3. class Context
  4. attr_reader :native, :scope, :access
  5. def initialize(opts = {})
  6. @access = Access.new
  7. @to = Portal.new(self, @access)
  8. @to.lock do
  9. with = opts[:with]
  10. constructor = nil
  11. template = if with
  12. constructor = @to.templates.to_constructor(with.class)
  13. constructor.disable()
  14. constructor.template.InstanceTemplate()
  15. else
  16. C::ObjectTemplate::New()
  17. end
  18. @native = opts[:with] ? C::Context::New(template) : C::Context::New()
  19. @native.enter do
  20. @global = @native.Global()
  21. @to.proxies.register_javascript_proxy @global, :for => with if with
  22. constructor.enable() if constructor
  23. @scope = @to.rb(@global)
  24. @global.SetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyContext"), C::External::New(self))
  25. end
  26. yield(self) if block_given?
  27. end
  28. end
  29. def eval(javascript, filename = "<eval>", line = 1)
  30. if IO === javascript || StringIO === javascript
  31. javascript = javascript.read()
  32. end
  33. err = nil
  34. value = nil
  35. @to.lock do
  36. C::TryCatch.try do |try|
  37. @native.enter do
  38. script = C::Script::Compile(@to.v8(javascript.to_s), @to.v8(filename.to_s))
  39. if try.HasCaught()
  40. err = JSError.new(try, @to)
  41. else
  42. result = script.Run()
  43. if try.HasCaught()
  44. err = JSError.new(try, @to)
  45. else
  46. value = @to.rb(result)
  47. end
  48. end
  49. end
  50. end
  51. end
  52. raise err if err
  53. return value
  54. end
  55. def load(filename)
  56. File.open(filename) do |file|
  57. self.eval file, filename, 1
  58. end
  59. end
  60. def [](key)
  61. @to.open do
  62. @to.rb @global.Get(@to.v8(key))
  63. end
  64. end
  65. def []=(key, value)
  66. @to.open do
  67. @global.Set(@to.v8(key), @to.v8(value))
  68. end
  69. return value
  70. end
  71. def self.stack(limit = 99)
  72. if native = C::Context::GetEntered()
  73. global = native.Global()
  74. cxt = global.GetHiddenValue(C::String::NewSymbol("TheRubyRacer::RubyContext")).Value()
  75. cxt.instance_eval {@to.rb(C::StackTrace::CurrentStackTrace(limit))}
  76. else
  77. []
  78. end
  79. end
  80. def self.passes_this_argument?
  81. true
  82. end
  83. end
  84. module C
  85. class Context
  86. def enter
  87. if block_given?
  88. if IsEntered()
  89. yield(self)
  90. else
  91. Enter()
  92. begin
  93. yield(self)
  94. ensure
  95. Exit()
  96. end
  97. end
  98. end
  99. end
  100. end
  101. end
  102. end