Граф коммитов

158 Коммитов

Автор SHA1 Сообщение Дата
naruse 587135e994 * vm.c (vm_exec): remove workaround for LLVM because r34278 fixes it.
* vm_insnhelper.c (vm_call_cfunc): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34345 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-01-20 08:39:24 +00:00
nagachika 0d9710692e * vm_insnhelper.c (unknown_keyword_error): add GC guard to prevent
intermediate object from GC.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34143 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-12-27 17:12:24 +00:00
mame c5e372ff27 * vm_insnhelper.c (unknown_keyword_error): make it kind a error message when unknown keyword is given. It require more work. See [ruby-core:40518] and [ruby-core:40541] in detail.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34138 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-12-26 14:20:20 +00:00
mame d0baa0dd52 * vm_core.h (struct rb_iseq_struct), compile.c (iseq_set_arguments), iseq.c (rb_iseq_parameters), vm_insnhelper.c (vm_callee_setup_arg_complex): support Method#parameters for keyword arguments. The provisional spec is what Benoit Daloze proposed. [ruby-core:40518]
* test/ruby/test_keyword.rb: add a test for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34137 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-12-26 14:20:15 +00:00
mame a0a2c144b8 * vm_core.h (struct rb_iseq_struct), compile.c (iseq_set_arguments, iseq_compile_each), vm_insnhelper.c (vm_callee_setup_arg_complex): implement keyword arguments. See [ruby-core:40290] The feature is promised to be included in 2.0, but the detail spec is still under discussion; this commit is a springboard for further discussion. Please try it and give us feedback. This commit includes fixes for some problems reported by Benoit Daloze <eregontp AT gmail.com> [ruby-core:40518] and Marc-Andre Lafortune <ruby-core-mailing-list AT marc-andre.ca> [ruby-core:41772].
* iseq.c (iseq_free, prepare_iseq_build): bookkeeping.

* test/ruby/test_keyword.rb: add tests for keyword arguments.

* test/ripper/dummyparser.rb (class DummyParser): temporal fix for
  ripper test.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34136 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-12-26 14:20:09 +00:00
nobu 50ae8a8651 * vm_insnhelper.c (vm_yield_setup_block_args): splat single
argument if optinal arguments are defined not only mandatory or
  post arguments.  [ruby-core:41557] [Bug #5730]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@34020 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-12-12 20:50:09 +00:00
nobu b526738c3b * bignum.c (big_rshift), compile.c (validate_label,
iseq_build_from_ary_exception), cont.c (cont_capture), dir.c
  (dir_open_dir), gc.c (objspace_each_objects), io.c (pipe_open)
  (rb_io_advise), parse.y (parser_compile_string)
  (rb_parser_compile_file), proc.c (binding_free), process.c
  (rb_proc_exec_n, rb_seteuid_core, proc_setegid, rb_setegid_core)
  (p_uid_exchange, p_gid_exchange), regparse.c (strdup_with_null),
  signal.c (sig_dfl), vm.c (rb_iseq_eval, rb_iseq_eval_main),
  vm_insnhelper.c (vm_expandarray): suppress
  unused-but-set-variable warnings.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33951 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-12-05 09:57:00 +00:00
tenderlove a5a7e2cd91 * vm_insnhelper.c (vm_call_cfunc): adding back useless hack. For some
reason, this fixes CFP errors on OS X 10.7.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33540 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-10-27 18:02:42 +00:00
kazu 171c708b0c fix typos
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33421 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-10-06 11:51:55 +00:00
nobu 89fef02f13 * vm_eval.c (make_no_method_execption): extract from
raise_method_missing().
* vm_eval.c (send_internal): remove inadvertent symbol creation
  from public_send.  based on a patch by Jeremy Evans <code AT
  jeremyevans.net> in [ruby-core:38576]. [Feature #5112]
* vm_insnhelper.c (vm_call_method): remove inadvertent symbol
  creation from send and __send__, too.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33419 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-10-06 07:29:33 +00:00
naruse 6340d6336a * vm_insnhelper.c (vm_call_cfunc): remove useless hack.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33408 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-10-05 07:35:31 +00:00
nobu 8e6e8e6288 * use RB_TYPE_P which is optimized for constant types, instead of
comparison with TYPE.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33357 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-09-29 11:07:45 +00:00
nobu 64b7b548e0 * vm_insnhelper.c (vm_call_cfunc): suppress a warning. note that
`volatile type *var' doesn't make var itself volatile.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33309 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-09-21 17:53:23 +00:00
naruse 192292af76 Avoid cfp consistency error by LLVM.
volatile is not enough.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33303 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-09-20 12:16:08 +00:00
nobu f957673826 * vm_insnhelper.c (vm_get_cvar_base): reduce duplicated checks and
move a warning outside the loop.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33302 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-09-20 09:09:00 +00:00
nobu 7dddaf6807 * vm_insnhelper.c (vm_search_const_defined_class): search
ancestors only when global scope.  [ruby-core:39227] [Bug #5264]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-09-02 05:36:49 +00:00
nobu 43284b6bf8 * insns.def (defineclass), vm_insnhelper.c (vm_get_cvar_base): see
also inherited constants for classes without superclass and
  modules.  [ruby-core:37698] [Bug #3423]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33157 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-09-01 08:31:24 +00:00
nahi cfe8ed5cbc * Re-apply r33078, thread-safe autoload which is reverted at r33093.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33146 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-08-31 08:28:19 +00:00
usa 13d3a16ada * vm_insnhelper.c (vm_call_cfunc): revert r33112. RB_GC_GUARD macro
protect a VALUE from GC.  It's not for general anti-optimizing
  purpose.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-08-30 13:28:58 +00:00
naruse 8ca1e6a0ee Use RB_GC_GUARD.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33112 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-08-29 06:51:48 +00:00
nahi 4d033a11c5 * Revert r33078. It caused a Rails application NoMethodError.
/home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/utils.rb:157: warning: toplevel constant ScanError referenced by Regin::Parser::ScanError
  /home/nahi/git/emptyApp/ruby/1.9.1/gems/rack-mount-0.6.14/lib/rack/mount/vendor/regin/regin/parser.rb:17:in `parse_regexp': undefined method `scan_str' for #<Regin::Parser:0x00000002344548> (NoMethodError)


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33093 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-08-27 02:19:42 +00:00
nahi 1e7f99dddf * variable.c: Make autoload thread-safe. See #921.
What's the problem?
    autoload is thread unsafe. When we define a constant to be
    autoloaded, we expect the constant construction is invariant. But
    current autoload implementation allows other threads to access the
    constant while the first thread is loading a file.

  What's happening inside?
    The current implementation uses Qundef as a marker of autoload in
    Constant table. Once the first thread find Qundef as a value at
    constant lookup, it starts loading a defined feature. Generally a
    loaded file overrides the Qundef in Constant table by module/class
    declaration at very beginning lines of the file, so other threads
    can see the new Module/Class object before feature loading is
    finished. It breaks invariant construction.

  How to solve?
    To ensure invariant constant construction, we need to override
    Qundef with defined Object after the feature loading. For keeping
    Qundef in Constant table, I expanded autoload_data struct in
    Module to have a slot for keeping the defined object while feature
    loading. And changed Module's constant lookup/update logic a
    little so that the slot is only visible from the thread which
    invokes feature loading. (== the first thread which accessed the
    autoload constant)

  Evaluation?
    All test passes (bootstrap test, test-all and RubySpec) and added
    8 tests for threading behavior. Extra logics are executed only
    when Qundef is found, so no perf drop should happen except
    autoloading.

* variable.c (rb_autoload): Prepare new autoload_data struct.

* variable.c (rb_autoload_load): Load feature and update Constant
  table after feature loading is finished. 

* variable.c (rb_const_get_0): When the fetched constant is under
  autoloading, it returns the object only for the thread which starts
  autoloading.

* variable.c (rb_const_defined_0): Ditto.

* variable.c (rb_const_set): When the specified constant is under
  autoloading, it sets the object only for the thread which starts
  autoloading. Otherwise, simply overrides Qundef with constant
  override warning.

* vm_insnhelper.c (vm_get_ev_const): Apply same change as
  rb_const_get_0 in variable.c.

* test/ruby/test_autoload.rb: Added tests for threading behavior.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33078 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-08-26 10:27:20 +00:00
ko1 beb26e1b49 * vm_insnhelper.h, vm_insnhelper.c, vm.c, vm_method.c, insns.def:
Manage a redefinition of special methods for each classes.
  A patch from Joel Gouly <joel.gouly@gmail.com>.  Thanks!



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33059 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-08-24 22:02:03 +00:00
ko1 7049d9c80d * iseq.h, iseq.c, compile.c: Change the line number data structure
to solve an issue reported at [ruby-dev:44413] [Ruby 1.9 - Bug #5217].
  Before this fix, each instruction has an information including
  line number (iseq::iseq_insn_info_table).  Instead of this data
  structure, recording only line number changing places
  (iseq::iseq_line_info_table).
  The order of entries in iseq_line_info_table is ascending order of
  iseq_line_info_table_entry::position.  You can get a line number
  by an iseq and a program counter with this data structure.
  This fix reduces memory consumption of iseq (bytecode).
  On my measurement, a rails application consumes 21.8MB for
  iseq with this fix on the 32bit CPU.  Without this fix, it
  consumes 24.7MB for iseq [ruby-dev:44415].
* proc.c: ditto.
* vm_insnhelper.c: ditto.
* vm_method.c: ditto.
* vm.c (rb_vm_get_sourceline): change to use rb_iseq_line_no().



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-08-24 06:31:15 +00:00
kosaki 5975e9e008 * vm_insnhelper.c (vm_call_cfunc): added volatile for a workaround
of cfp consistency error problem on OS X 10.7 (Lion). It's
  suspected llvm optimization bug.
  [Bug #5076] [ruby-dev:44185]



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32628 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-07-22 12:52:25 +00:00
ko1 9cf9d5eaf7 * vm_insnhelper.c (vm_throw): check a class frame.
Fixes Bug #4648.
  The patch is contributed by Kazuki Tsujimoto.
* bootstraptest/test_proc.rb: add tests for above.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-07-10 09:04:44 +00:00
ko1 2e4fb84f7c * vm_insnhelper.c (vm_getivar): check vm state version
to invalidate inline chache (ivar index).
  fixes Bug #4926.
* vm_insnhelper.c (vm_setivar): ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32347 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-30 23:23:32 +00:00
ko1 065fe8b7a4 * vm_insnhelper.c (vm_call_bmethod): fix to hook call/return event
for methods defined by define_method().
* thread.c (call_trace_proc): Fix to skip if class is not given (0).
  Note that ID and Class object are passed for call/return event
  if the called method was defined by define_method().
  If you are author of tracer/profiler/debugger, this may be an
  important change.  You should check passed class as zero or
  non-zero instead of checking the event type.
* test/ruby/test_settracefunc.rb: add a test for above.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32334 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-30 13:34:53 +00:00
nagachika 9c931b853b * vm_insnhelper.c (vm_search_superclass): avoid control frame
stack overrun. currently super() in Proc created in a method
  defined by Module#define_method raise NoMethodError. [Bug #4881]
* test/ruby/test_method.rb t_super_in_proc_from_define_method):
  add test for it.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32227 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-25 15:05:37 +00:00
naruse be953b4d1c * cont.c (cont_capture): add volatile.
On clang -O, it is needed to avoid the optimization.
  With this and llvm/clang's recent fix, clang 3.0 can
  build ruby-trunk with -O option.

* cont.c (cont_capture): use for-loop.

* array.c (rb_ary_each): add volatile and use it.

* vm_insnhelper.c (vm_call_cfunc): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-22 11:00:24 +00:00
akr 7da3ea811e * method.h, internal.h iseq.h: declare internal functions.
* compile.c, eval.c, iseq.c, object.c, parse.y, proc.c, process.c,
  thread.c, vm.c, vm_eval.c, vm_insnhelper.c, vm_method.c: don't
  declare internal functions.

  Note that rb_method_entry_eq() is defined in vm_method.c but
  there was a declaration in proc.c with different const-ness.
  Now it is declared in method.h with same const-ness to the
  definition.

* object.c (rb_mod_module_exec): don't declare functions declared in
  include/ruby/intern.h.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32163 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-18 03:49:33 +00:00
kosaki 3c23284734 * thread.c (rb_thread_schedule_rec): fix {UN,}LIKELY macro misuse.
* gc.c (rb_newobj): ditto.
* vm_insnhelper.c (vm_method_search): ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32131 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-06-16 14:42:02 +00:00
nobu 52f5f410e4 * internal.h: add for internal use only.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-05-18 13:41:54 +00:00
shugo 7487298584 * vm_insnhelper.c (vm_get_ev_const): should ignore crefs with
the NODE_FL_CREF_PUSHED_BY_EVAL flag.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31222 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-03-31 09:07:42 +00:00
shugo 4273aa8e72 * vm_insnhelper.c (vm_get_ev_const): search root cref properly.
[ruby-dev:43365]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31221 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-03-31 07:52:40 +00:00
nobu d3326ddf11 * vm_insnhelper.c (vm_get_ev_const): should not autoload in
defined? mode.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@31170 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-03-24 14:06:31 +00:00
nobu e7c0a6e1d7 * prevent temporary objects from GC, and should not use
RSTRING_PTR() for function calls since it evaluates the argument
  a couple of times.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30922 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-02-20 07:23:55 +00:00
nagachika e3cc834486 * vm_insnhelper.c (vm_check_if_namespace): guard temporary object
from GC.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30916 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-02-19 13:41:19 +00:00
mame 5b74e4f09e * vm_insnhelper.c (vm_get_ev_const): no-scope reference to toplevel
private constant has been prohibited incorrectly.

* test/ruby/test_module.rb (test_toplevel_private_constant): add a
  test for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30718 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-01-29 02:01:19 +00:00
mame f0483c494f * constant.h, variable.c: to ensure compatibility, rb_const_get_* must
not raise an exception even when the constant is private.  Instead,
  rb_public_const_get_* and rb_public_const_defined_* are introduced,
  which raise an exception when the referring constant is private.
  see [ruby-core:32912].

* vm_insnhelper.c (vm_get_ev_const): use rb_public_const_get_* instead
  of rb_const_get_* to follow the constant visibility when user code
  refers a constant.

* test/ruby/test_marshal.rb (test_marshal_private_class): add a test.
  This test had failed because of incompatibility of rb_const_get.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30713 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-01-28 17:57:27 +00:00
akr def8c8c347 * vm_insnhelper.c: parenthesize macro arguments.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30534 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2011-01-13 11:49:54 +00:00
nobu f4db8aedc8 * compile.c (setup_args), vm.c (invoke_block_from_c),
vm_insnhelper.c (caller_setup_args): reverted r30241 and r30243
  except for the test.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30283 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-12-20 21:10:24 +00:00
nobu cd3f980ea2 * compile.c (setup_args), vm.c (invoke_block_from_c),
vm_insnhelper.c (caller_setup_args): fix of r30241. lambda block
  shoud check argument number.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30243 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-12-18 07:02:35 +00:00
nobu 202cb99c86 * iseq.c (set_relation), vm_insnhelper.c (vm_cref_push): nd_file
is always zero-cleared.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30223 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-12-15 22:51:51 +00:00
nobu b942e7891a * vm_insnhelper.c (vm_call_method): revert r30064 and r30071,
because of [ruby-core:26761]. Bug#4106 rejected.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30074 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-12-03 23:25:19 +00:00
nobu 7b0b9df60e * vm_insnhelper.c (vm_call_method): protected methods should be
checked against the real class.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30071 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-12-03 13:36:49 +00:00
nobu adc978adc3 * vm_insnhelper.c (vm_call_method): protected singleton methods should
be visible from same real class methods.  [ruby-core:33506]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30064 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-12-03 03:17:22 +00:00
mame 6cba0f0663 * vm_insnhelper.c (vm_throw): remove fear of undefined behavior :-)
Coverity Scan found this bug.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29807 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-11-16 13:32:30 +00:00
mame a115768161 * class.c, constant.h, gc.c, method.h, object.c, variable.c,
vm_insnhelper.c: use struct rb_constant_entry_t as entry of
  RCLASS_CONST_TBL.  RCLASS_CONST_TBL has contained VALUE of constant
  directly.  Now instead rb_const_entry_t is contained in
  RCLASS_CONST_TBL,  rb_const_entry_t is managed by malloc, and
  have not only the value itself but also visibility flag.
  This is another preparation for private constant (see
  [ruby-dev:39685][ruby-core:32698]).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29602 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-10-26 17:27:32 +00:00
mame 2285a8d813 * class.c, gc.c, object.c, variable.c, vm_insnhelper.c,
include/ruby/ruby.h: separate RCLASS_CONST_TBL from RCLASS_IV_TBL.
  RCLASS_IV_TBL has contained not only instance variable table but
  also constant table.  Now the two table are separated to
  RCLASS_CONST_TBL and RCLASS_IV_TBL.  This is a preparation for
  private constant (see [ruby-dev:39685][ruby-core:32698]).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29600 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2010-10-26 17:27:21 +00:00