Compare commits

...

518 Commits

Author SHA1 Message Date
Hiroshi Mimaki b6b9c57f24 Update version to 2.1.2. (mruby 2.1.2 RC) 2020-07-01 16:49:21 +09:00
Hiroshi Mimaki aa578c346d Revert "Free the original pointer if realloc failed."
This reverts commit 9cdf439db5.
2020-06-30 18:33:47 +09:00
Yukihiro "Matz" Matsumoto ac8360003e Fix the bug that mrbc generates a.rb.mrb instead of a.mrb.
The bug was introduced by 9dfe50f1d.
2020-06-29 07:25:03 +09:00
Yukihiro "Matz" Matsumoto 233cb49903 Remove unnecessary stack adjustment in OP_CALL. 2020-06-25 06:57:43 +09:00
Yukihiro "Matz" Matsumoto 9cdf439db5 Free the original pointer if realloc failed.
The POSIX `realloc` keep the original pointer untouched, so it can
easily leads to memory leakage. `mrb_realloc()` should handle those
bookkeeping, while `mrb_realloc_simple()` keeps the original `realloc`
behavior.
2020-06-25 06:57:43 +09:00
Yukihiro "Matz" Matsumoto 95360a17f2 Remove unnecessary break from numeric.c. 2020-06-25 06:57:42 +09:00
Yukihiro "Matz" Matsumoto 9dfe50f1d9 Use snprintf instead of memcpy in mrbc.c. 2020-06-25 06:57:42 +09:00
Yukihiro "Matz" Matsumoto c07f24cd18 Change flag names in preparation of REnv refactoring. 2020-06-25 06:57:41 +09:00
Yukihiro "Matz" Matsumoto 03c2b8656b Use mrb_get_argc() to improve performance. 2020-06-25 06:57:41 +09:00
Yukihiro "Matz" Matsumoto ea6e1b003c Create codeql-analysis.yml 2020-06-23 12:36:20 +09:00
Yukihiro "Matz" Matsumoto c2b37e76b3 Skip mrb_get_args() in mrb_ary_{aget,aset} unless necessary.
Use simpler `mrb_get_argc()` and `mrb_get_arg1()` instead.
2020-06-22 21:47:23 +09:00
Yukihiro "Matz" Matsumoto d40b922c98 Fix potential buffer overflow in sprintf.c. 2020-06-20 18:56:33 +09:00
Yukihiro "Matz" Matsumoto 28e793496a Support integer and float combination in mrb_equal(). 2020-06-20 18:56:05 +09:00
Yukihiro "Matz" Matsumoto 33c8d6af1e Move definition of BasicObject#!= to mrblib.
C implementation used `mrb_funcall()` that bypassed many optimization.
2020-06-20 14:09:23 +09:00
Yukihiro "Matz" Matsumoto 49ae2a69f2 Add mrb_get_arg1() that retrieves single (and only) argument.
`mrb_get_arg1()` raises `ArgumentError` if the method does not receive one
argument.

And replaces all `mrb_get_args(mrb, "o", &arg)` by the new function.
2020-06-20 12:49:46 +09:00
Yukihiro "Matz" Matsumoto 2ffb77586a Symbolify saved alias name to improve performance. 2020-06-20 12:07:49 +09:00
Yukihiro "Matz" Matsumoto dad99afae8 Remove unnecessary comments from MRB_TT_* definitions. 2020-06-15 09:54:55 +09:00
Yukihiro "Matz" Matsumoto f93dffb5ee Remove unused MRB_TT_FILE. 2020-06-15 07:47:22 +09:00
Yukihiro "Matz" Matsumoto 742117e7a3 Reorganize gray mark functions in GC. 2020-06-11 16:18:52 +09:00
Yukihiro "Matz" Matsumoto 15ceb35e05 Remove GC test code from ancient. 2020-06-11 16:18:51 +09:00
Yukihiro "Matz" Matsumoto f0bad600e0 Remove endian configuration methods.
Since we made our opcode byte based, we need no endian option (`-e`
and `-E`) to `mrbc`.
2020-06-11 16:18:50 +09:00
Yukihiro "Matz" Matsumoto a8aeba89ef Merge pull request #5023 from dearblue/nesting
Remove `mrb_assert()` in `Module.nesting`
2020-06-11 12:21:26 +09:00
Yukihiro "Matz" Matsumoto 7f593893e8 Update OP_HASH generation to support big hash creation. 2020-06-09 22:42:38 +09:00
Yukihiro "Matz" Matsumoto 5d5b1d1f3c Merge pull request #5022 from dearblue/test-dir
Need `build/XXX/mrbgems/mruby-test` directory
2020-06-09 22:42:29 +09:00
Yukihiro "Matz" Matsumoto bb6846468a Merge pull request #5021 from dearblue/kernel-test
Update `test/t/kernel.rb`
2020-06-09 22:41:44 +09:00
dearblue 960c82e396 Remove mrb_assert() in Module.nesting
The following code was causing SIGSEGV:

```ruby
Module.method(:nesting).call
```
2020-06-09 21:54:13 +09:00
dearblue 5be33b82c7 Need build/XXX/mrbgems/mruby-test directory
An error may occur when performing `rake clean all` or `rake clean test`.

The directory is needed before writing to `mrbgems/mruby-test/assert.c`.
2020-06-09 21:24:53 +09:00
dearblue 4cd858f93d Update test/t/kernel.rb
- Remove unnecessoury assert
- Fix typo
2020-06-09 20:33:56 +09:00
Yukihiro "Matz" Matsumoto 2098acee7d Merge pull request #5020 from jethrodaniel/master
only use GEMNAME if defined in assert.rb
2020-06-08 15:51:03 +09:00
Mark Delk 3157efa57c only use GEMNAME if defined in assert.rb
Check if the constant GEMNAME is defined before use in `assert.rb`.

This is added to prevent an undefined constant error when using
`assert.rb` in other environments - for example, testing CRuby.
2020-06-08 00:30:46 -05:00
Yukihiro "Matz" Matsumoto 613e0bee5e Merge pull request #5013 from shuujii/print-exception-backtrace-if-possible-without--v-in-test
Print exception backtrace if possible without `-v` in test
2020-06-08 09:59:43 +09:00
Yukihiro "Matz" Matsumoto 78c9c71bdf Add proper cast. 2020-06-05 17:52:22 +09:00
Yukihiro "Matz" Matsumoto aa30b13b36 Change arena index from mrb_int to int. 2020-06-05 17:26:40 +09:00
Yukihiro "Matz" Matsumoto 6ba542cd53 Revert part of #5019 (mruby_io_test.c) to honor #4987
The issue was reported by @shuujii.
2020-06-05 17:20:41 +09:00
Yukihiro "Matz" Matsumoto 106f4c4e9d Add proper casts to silence VC warnings. 2020-06-05 16:04:30 +09:00
Yukihiro "Matz" Matsumoto f1523d2404 Squashed commit of the following:
commit 2d7d545c4c4bfce7fdcbcbe9baaeb437915742f0
Merge: 625a1249 b178914b
Author: Yukihiro "Matz" Matsumoto <matz@ruby.or.jp>
Date:   Fri Jun 5 14:35:13 2020 +0900

    Merge branch 'fix-mrb_open-with-nomem' of https://github.com/dearblue/mruby into dearblue-fix-mrb_open-with-nomem

commit b178914b11
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sat Jan 19 22:22:44 2019 +0900

    Fix invalid pointer free inside other heap's block

     1. `e = mrb_obj_alloc(...)`
     2. `e->stack = mrb->c->stack` (`mrb->c->stack` is anywhere in the range `stbase...stend`)
     3. And raised exception by `mrb_malloc()`!
     4. `mrb_free(e->stack)` by GC part (wrong free)

commit 52e3d5d858
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sat Jan 19 21:55:36 2019 +0900

    Fix memory leak for temporary symbols when out of memory

commit 4c5499b88e
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 11:42:07 2019 +0900

    Fix uninitialized pointer dereference for debug section

commit 8e993167de
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 11:41:09 2019 +0900

    Fix memory leak for temporary filenames when out of memory

commit 8b422577e6
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 10:57:51 2019 +0900

    Fix memory leak for irep when out of memory

commit 6b35ebf49a
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 10:55:50 2019 +0900

    Fix uninitialized pointer dereference when do not finished initializing irep

commit 2531f2631e
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 10:48:15 2019 +0900

    Fix NULL pointer dereference when do not finished initializing irep

commit e2d6896eba
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sat Jan 19 12:54:19 2019 +0900

    Fix memory leak for irep when out of memory by `mrb_proc_new()`

commit b6214ff8a0
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sat Jan 19 12:53:07 2019 +0900

    Fix memory leak for `khash_t` in `kh_init_size()` when out of memory by `kh_alloc()`

commit 19162dd6c1
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 02:15:07 2019 +0900

    Fix memory leak for symbol string when out of memory in `kh_put()`

commit 15e67297ff
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 02:12:24 2019 +0900

    Fix keep wrong symbol index when out of memory

commit 3f8e2b3752
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 02:08:13 2019 +0900

    Fix keep wrong symbol capacity when out of memory

commit a3cfe755ab
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sat Jan 19 10:11:37 2019 +0900

    Fix NULL pointer dereference `mrb->c` by `mark_context()`

commit d9c7b6be6e
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 15:25:09 2019 +0900

    Fix protect exception for print error message

commit 100642750e
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 11:59:02 2019 +0900

    Protect exception for mruby core initialization

commit 7a0418304e
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Fri Jan 18 20:38:27 2019 +0900

    Fix memory leak for string object when out of memory

    The `mrb_str_pool()` function has a path to call `malloc()` twice.

    If occurs `NoMemoryError` exception in second `malloc()`,
    first `malloc()` pointer is not freed.

commit fef1c152ce
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sat Jan 19 13:05:09 2019 +0900

    Fix stack overflow when out of memory

    As a result of this change, no backtrace information is set
    for NoMemoryError (`mrb->nomem_err`).

    Detailes:

    When generating a backtrace, called `mrb_intern_lit()`,
    `mrb_str_new_cstr()` and `mrb_obj_iv_set()` function with
    `exc_debug_info()` function in `src/error.c`.

    If a `NoMemoryError` exception occurs at this time,
    the `exc_debug_info()` function will be called again,
    and in the same way `NoMemoryError` exception raised will result
    in an infinite loop to occurs stack overflow (and SIGSEGV).

commit da7d7f881b
Author: dearblue <dearblue@users.noreply.github.com>
Date:   Sun Jan 20 12:00:38 2019 +0900

    Fix NULL pointer dereference `mrb->nomem_err` when not initialized

    Add internal functions (not `static`):

      * `mrb_raise_nomemory()`
      * `mrb_core_init_abort()`
2020-06-05 14:40:07 +09:00
Yukihiro "Matz" Matsumoto 00f6271e3b Change arena index from mrb_int to int. 2020-06-05 14:40:07 +09:00
Yukihiro "Matz" Matsumoto b0e49ef79e Merge pull request #5019 from mruby/stable
Merge mruby 2.1.1
2020-06-05 13:04:36 +09:00
Hiroshi Mimaki 81d340e042 Merge master. 2020-06-05 12:42:56 +09:00
Yukihiro "Matz" Matsumoto 4e40169ed6 Remove rake -v option from GitHub Actions. 2020-06-04 18:24:58 +09:00
Yukihiro "Matz" Matsumoto 49f1c0e94d Ignore files for clangd.
- `compile_flags.txt'
- `compile_commands.json`
2020-06-04 18:09:03 +09:00
Yukihiro "Matz" Matsumoto dcfebc6eed Remove bison installation from GitHub Actions. 2020-06-04 18:08:08 +09:00
Hiroshi Mimaki f9d113f764 Update release date. 2020-06-04 17:20:46 +09:00
Yukihiro "Matz" Matsumoto 3d2d9f8a9b Add explicit cast to DROP_PRECISION macro in rtional.c. 2020-06-04 11:01:31 +09:00
Yukihiro "Matz" Matsumoto 07129c76d9 Add mruby-complex and mruby-rational to default.gembox. 2020-06-04 11:01:30 +09:00
Yukihiro "Matz" Matsumoto 6fe03f3b39 Add explicit cast to silence warnings on AppVeyor. 2020-06-04 11:01:30 +09:00
Yukihiro "Matz" Matsumoto 41f3456a28 Merge pull request #4865 from take-cheeze/istruct_align
Align RIStruct data for rational/complex
2020-06-04 11:01:04 +09:00
Yukihiro "Matz" Matsumoto 7a420d4bba Add .ccls* to .gitignore. 2020-06-04 10:05:42 +09:00
Yukihiro "Matz" Matsumoto d2b9c90f28 Merge branch 'dearblue-hide-func'; merge #4937 2020-06-03 14:16:11 +09:00
dearblue ce12ef7e5c Hiding method implementation C functions in mruby-io 2020-06-03 14:12:51 +09:00
Yukihiro "Matz" Matsumoto 8bca11a64e Merge pull request #4800 from shuujii/set-MRB_STR_ASCII-flag-to-some-stringize-methods
Set `MRB_STR_ASCII` flag to some stringize methods
2020-06-03 14:01:52 +09:00
Yukihiro "Matz" Matsumoto 14e325e45d Merge branch 'dearblue-eval-patchfree'; close #5016 2020-06-02 14:49:49 +09:00
dearblue f85906b679 Remove patch_irep() in mruby-eval
- It can now deal with operands in the range of `OP_EXT*`.
- It can now call the same method as the variable name without arguments.

  ```ruby
  def a
    "Safe!"
  end

  a = "Auto!"

  eval "a()" # call method `a`
  ```
2020-06-02 14:49:27 +09:00
Yukihiro "Matz" Matsumoto 1fc9345b45 Add mruby-eval to default.gembox. 2020-06-01 23:00:37 +09:00
Yukihiro "Matz" Matsumoto 0a5983dd5e Merge pull request #5014 from dearblue/local_variables
Get local variable names from orphan block; ref #3710
2020-06-01 22:58:17 +09:00
Yukihiro "Matz" Matsumoto aec40d10b8 Merge pull request #5017 from RoryO/master
Fix float constant redefinition warnings
2020-06-01 21:26:57 +09:00
Rory OConnell 89ceb3e7ba Fix float constant redefinition warnings 2020-05-31 20:11:38 -07:00
dearblue fc80e4b651 Get local variable names from orphan block; ref #3710 2020-05-31 15:56:04 +09:00
KOBAYASHI Shuji 52ab095ccf Print exception backtrace if possible without -v in test
Backtrace is useful for debugging.
2020-05-29 13:46:16 +09:00
Yukihiro "Matz" Matsumoto d5cca2bdb2 Check c->eidx before decrement in ecall(); close #4977 2020-05-28 18:53:27 +09:00
Yukihiro "Matz" Matsumoto ebbb4fd7fb Merge pull request #5011 from shuujii/respect-CFLAGS-CXXFLAGS-and-LDFLAGS-env-vars-in-appveyor_config.rb
Respect CFLAGS, CXXFLAGS, and LDFLAGS env vars in appveyor_config.rb
2020-05-27 22:15:44 +09:00
KOBAYASHI Shuji b717cc7830 Respect CFLAGS, CXXFLAGS, and LDFLAGS env vars in appveyor_config.rb
[skip travis]
2020-05-27 16:50:44 +09:00
Yukihiro "Matz" Matsumoto a476c83caf Move fmt_setup until absolutely necessary. 2020-05-27 14:09:36 +09:00
Yukihiro "Matz" Matsumoto 15c63688e3 Integer format can be bigger than 32 on 64bit platforms.
We made it `64` which should be big enough:
- Format modifier: 4 characters max
- Maximum width: 19 digits max
- Period between width and precision: 1 character
- Maximum precision: 19 digits max
- Format specifier: 1 character
- NUL terminator: 1 byte
- Total: 45 < 64
2020-05-26 23:53:16 +09:00
Yukihiro "Matz" Matsumoto 69c62415c0 Merge pull request #5010 from udzura/patch-1
Detect newly added mrbgems when re-creating gem_init.c
2020-05-26 23:37:22 +09:00
Kondo Uchio 690b2aa761 Detect newly added mrbgems when re-creating gem_init.c 2020-05-26 23:15:00 +09:00
Yukihiro "Matz" Matsumoto 69311fa4c9 Merge pull request #5009 from shuujii/removed-Bison-related-settings-from-.travis.yml-and-appveyor.yml
Removed Bison related settings from `.travis.yml` and `appveyor.yml`
2020-05-26 20:17:49 +09:00
Yukihiro "Matz" Matsumoto ab9be1b48a Merge pull request #5008 from shuujii/revert-part-of-Start-GitHub-Actions
Revert part of "Start GitHub Actions" (4ce3997c)
2020-05-26 12:43:38 +09:00
KOBAYASHI Shuji 5a682bfc7b Removed Bison related settings from .travis.yml and appveyor.yml 2020-05-26 11:56:35 +09:00
KOBAYASHI Shuji 53ea8abea6 Revert part of "Start GitHub Actions" (4ce3997c)
Because some changes have been overridden.
2020-05-26 11:48:42 +09:00
Yukihiro "Matz" Matsumoto 6445e4683f Specify the latest bison on macOS; ref #4903 2020-05-26 08:17:39 +09:00
Yukihiro "Matz" Matsumoto 6d49ec25a9 Merge pull request #5007 from shuujii/add-y.tab.c-to-remove-Bison-from-build-dependencies
Add `y.tab.c` to remove Bison from build dependencies; ref 4ce3997c
2020-05-26 08:17:23 +09:00
KOBAYASHI Shuji a3ec6ede76 Add y.tab.c to remove Bison from build dependencies; ref 4ce3997c
I sometimes see Bison related problems in setting up build environments.
Therefore to remove Bison from build time dependencies, add `y.tab.c`
generated by Bison to the repository.

The reduction of dependency at build time also reduces the labor and time
for setup and installation in CI.

In addition, a path in `#line` directive is converted to a relative path so
that its path is constant regardless of development environments.
2020-05-25 23:26:30 +09:00
Yukihiro "Matz" Matsumoto 6803ddb8e2 Use the newer bison on GitHub actions macOS; ref #4903
`Windows-MinGW` and `Windows-VC` also requires updates.
2020-05-24 23:12:27 +09:00
Takeshi Watanabe 4ce3997ca4 Start GitHub Actions; close #4903 2020-05-24 22:34:28 +09:00
Yukihiro "Matz" Matsumoto 93e78fcde1 Merge pull request #5006 from mame/fix-send-with-splat-args
Do not destruct rest arguments for __send__
2020-05-24 08:31:06 +09:00
Yusuke Endoh 6f4c585bd7 Do not destruct rest arguments for __send__
Formerly, `__send__(*args)` modified `args` with `Array#shift`.
This bug affects optcarrot.

This changeset avoids the array destruction by using
`args = args[1, len-1]`.
2020-05-24 01:25:03 +09:00
Yukihiro "Matz" Matsumoto 47ea60814b Merge pull request #5003 from shuujii/retry-rake--m-on-AppVeyor
Retry `rake -m` on AppVeyor [skip travis]
2020-05-20 13:49:10 +09:00
KOBAYASHI Shuji 86223b6eca Retry rake -m on AppVeyor [skip travis]
The following error occurs when using `rake -m` on AppVeyor:

  ```
  fatal error C1041: cannot open program database 'C:\projects\mruby\vc140.pdb'; if multiple CL.EXE write to the same .PDB file, please use /FS
  ```

Therefore, the issue is solved by not creating the PDB file. It is expected
to be somewhat faster by not generating debugging information (I don't think
debugging information is necessary for normal CI).
2020-05-20 13:32:23 +09:00
Yukihiro "Matz" Matsumoto d79147fe5d Revert "Use rake -m (multi-task) to appveyor.yml."
This reverts commit ac68c90800.
`rake -m` does not work for VisualC.
2020-05-19 22:42:19 +09:00
Yukihiro "Matz" Matsumoto ac68c90800 Use rake -m (multi-task) to appveyor.yml. 2020-05-19 17:37:17 +09:00
Yukihiro "Matz" Matsumoto 82194c01ca Merge pull request #5002 from RoryO/master
Adding warnings for mrb_load functions leaking RProc objects
2020-05-19 17:34:56 +09:00
Rory OConnell 69bc477b43 Adding warnings for mrb_load functions leaking RProc objects 2020-05-19 01:07:49 -07:00
Yukihiro "Matz" Matsumoto 3655d4e0f4 Merge pull request #5000 from shuujii/unify-eql-receiver-in-Hash-according-to-Ruby
Unify `eql?` receiver in `Hash` according to Ruby
2020-05-15 23:42:19 +09:00
KOBAYASHI Shuji bc929656fb Unify eql? receiver in Hash according to Ruby
### Example

  ```ruby
  # example.rb
  class A
    def eql?(o)
      p self.class
      super
    end
    def hash
      1
    end
  end

  class B < A; end

  h = {A.new => 1}
  h[B.new]
  ```

#### Before this patch:

  ```console
  $ bin/mruby example.rb
  A
  ```

#### After this patch (same as Ruby)

  ```console
  $ bin/mruby example.rb
  B
  ```
2020-05-15 21:17:24 +09:00
Yukihiro "Matz" Matsumoto 4aba93c969 Rename C function mrb_proc_lambda. 2020-05-15 15:55:35 +09:00
Yukihiro "Matz" Matsumoto 49d97d6051 Add pread/pwrite support on __MACH__ (MacOS) in addition to __unix__. 2020-05-15 12:31:18 +09:00
Yukihiro "Matz" Matsumoto 484577670f Remove YYERROR_VERBOSE which no longer supported since bison 3.6.
Instead we added `%define parse.error verbose`.
2020-05-15 12:30:13 +09:00
Yukihiro "Matz" Matsumoto d64c4d64e6 Make off_t handling simpler; #4872 #4939
The newer `clang` warns implicit float conversions.
2020-05-11 10:14:25 +09:00
Yukihiro "Matz" Matsumoto 846af371c0 Merge pull request #4998 from dearblue/special-vars
Get an irep symbol if it's `OP_GETSV` or `OP_SETSV`
2020-05-11 09:59:23 +09:00
Yukihiro "Matz" Matsumoto 38b4483f9d Merge pull request #4999 from dearblue/opcode-doc
Update `doc/opcode.md` [ci skip]
2020-05-11 09:58:11 +09:00
dearblue bb2512641f Update doc/opcode.md [ci skip]
The difference of `include/mruby/ops.h` is applied.

- OP_NOP - update semantics
- OP_GETSV - update semantics
- OP_SETSV - update semantics
- OP_GETUPVAR - update prefix
- OP_SETUPVAR - update prefix
- OP_JMPIF - update operands and semantics
- OP_JMPNOT - update operands and semantics
- OP_JMPNIL - add entry
- OP_ONERR - update semantics
- OP_POPERR - update prefix
- OP_EPOP - update prefix
- OP_SENDB - update semantics
- OP_ADD - update prefix and operands
- OP_ADDI - update operands and semantics
- OP_SUB - update prefix and operands
- OP_SUBI - update semantics
- OP_MUL - update prefix and operands
- OP_DIV - update prefix and operands
- OP_EQ - update prefix and operands
- OP_LT - update prefix and operands
- OP_LE - update prefix and operands
- OP_GT - update prefix and operands
- OP_GE - update prefix and operands
- OP_ARYDUP - add entry
- OP_INTERN - add entry
- OP_HASHCAT - add entry
- OP_ERR - update semantics
2020-05-10 20:34:10 +09:00
dearblue bd60ad98eb Get an irep symbol if it's OP_GETSV or OP_SETSV 2020-05-10 20:15:55 +09:00
Yukihiro "Matz" Matsumoto 7826af38ac Merge pull request #4997 from dearblue/byteorder
Remove byteorder constants; ref 87576b8
2020-05-09 23:01:02 +09:00
Yukihiro "Matz" Matsumoto 84d842ea5c Merge pull request #4996 from dearblue/loadi16
Fix boundary check for `OP_LOADI16`; ref fa8668c
2020-05-09 22:41:23 +09:00
dearblue f6c2662632 Remove byteorder constants; ref 87576b8
The `FLAG_BYTEORDER_NATIVE` and `FLAG_BYTEORDER_NONATIVE` are no longer
needed.
2020-05-09 22:30:05 +09:00
dearblue e2aecacaeb Fix boundary check for OP_LOADI16; ref fa8668c
It was making a negative integer if the highest-order bit of a 16-bit
integer was 1.

no patched:

```ruby
p 0x7fff  # => 32767
p 0x8000  # => -32768
p 0xffff  # => -1
p 0x10000 # => 65536
```
2020-05-09 21:12:31 +09:00
Yukihiro "Matz" Matsumoto 8cdf6a87ed Merge pull request #4995 from shuujii/fix-some-Hash-methods-are-inconsistent-with-values
Fix some `Hash` methods are inconsistent with `values`
2020-05-09 18:59:22 +09:00
KOBAYASHI Shuji 181f7b97d6 Fix some Hash methods are inconsistent with values
Inconsistent when hash has duplicate key.

### Example

  ```ruby
  # example.rb
  keys = (1..3).map{[_1]}
  h = keys.to_h{[_1, _1[0]]}
  keys[0][0] = 2
  p h.values
  p h.each_value.to_a
  p h
  ```

#### Before this patch:

  ```console
  $ bin/mruby example.rb
  [1, 2, 3]
  [1, 1, 3]
  {[2]=>1, [2]=>1, [3]=>3}
  ```

#### After this patch (same as Ruby)

  ```console
  $ bin/mruby example.rb
  [1, 2, 3]
  [1, 2, 3]
  {[2]=>1, [2]=>2, [3]=>3}
  ```
2020-05-09 15:27:42 +09:00
Yukihiro "Matz" Matsumoto 3491372a1d Update doc/opcode.md for operand signs. [ci skip] 2020-05-07 18:41:43 +09:00
Yukihiro "Matz" Matsumoto 03b0741994 Remove unnecessary sprintf test that fails since 91368c1. 2020-05-07 10:31:49 +09:00
Yukihiro "Matz" Matsumoto a87f0b158d Update README.md to address old bison problem on macOS. 2020-05-07 10:17:38 +09:00
Yukihiro "Matz" Matsumoto 5e01674b72 Should not use assert with expressions with side-effect; ref #4981
`assert()` can be completely removed when `NDEBUG` is set.
2020-05-07 09:37:02 +09:00
Yukihiro "Matz" Matsumoto b652a4ff14 Fixed wrong condition in #4981. 2020-05-07 09:36:43 +09:00
Yukihiro "Matz" Matsumoto 7dc0fe66c7 Add #include <string.h> on all platforms for strncpy; #4981 2020-05-07 09:36:21 +09:00
Yukihiro "Matz" Matsumoto 1cdcd00cc0 Remove unused local variable if MRB_UTF8_STRING is not set.
Ref #4982 #4983
2020-05-07 09:35:47 +09:00
Yukihiro "Matz" Matsumoto 9f4b5227fe Avoid snprintf in mruby-io test; ref #4981 2020-05-07 09:33:44 +09:00
Yukihiro "Matz" Matsumoto d464fe5003 Remove the temporary file from the AF_UNIX socket test; #4981 2020-05-07 09:33:08 +09:00
Yukihiro "Matz" Matsumoto 6b839b2319 Fix IO#readchar to return broken UTF-8 rather than EOF error.
The behavior is different from CRuby, but we believe this is a right
behavior for mruby, which only supports either ASCII or UTF-8
exclusively; fix #4983, ref #4982

```
$ printf '\xe3\x81' | ruby -e 'p STDIN.readchar'
"\xE3\x81"
```

```
$ printf '\xe3\x81' | mruby -e 'p STDIN.readchar'
"\xE3"
```
2020-05-07 09:32:46 +09:00
Yukihiro "Matz" Matsumoto 45bd372755 Fix IO#readchar to support UTF-8 char reading; fix #4712
This fix only effective when `MRB_UTF8_STRING` is set.
2020-05-07 09:31:38 +09:00
Yukihiro "Matz" Matsumoto f5ee7df7f3 Rename (and expose) UTF-8 related functions; ref #4712
- mrb_utf8len() - returns the size of a UTF-8 char (in bytes)
- mrb_utf8_strlen() - returns the length of a UTF-8 string (in char)
2020-05-07 09:31:07 +09:00
Yukihiro "Matz" Matsumoto e82b8b7bf8 Update cmpnum document.
`cmpnum` function may return `nil` on error.
2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 91368c117c Avoid mrb_funcall if MRB_UFT8_STRING is not set. 2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 87576b819e Remove endian information/flags from compiled binary format.
Since `mruby 2.0`, compiled bytecode no longer depends on the
endian of the machine.
2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 48c473a0c4 Remove -e/-E options from mrbc.
You don't have to specify endian since `mruby 2.0`.
2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 87d77c13f5 Update compiled binary format version for OP_LOADI16. 2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 4188219620 Update doc/opcode.md to reflect the latest bytecode.
- Add `OP_LOADI16`
- Update keyword argument related ops (e.g. OP_KEY_P, etc.)
- Fix some wrong descriptions
2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto fa8668c77d Add a new instruction OP_LOADI16.
Which loads 16bit integer to the register. The instruction number should
be reorder on massive instruction refactoring. The instruction is added
for `mruby/c` which had performance issue with `OP_EXT`. With this
instruction, `mruby/c` VM can just raise errors on `OP_EXT` extension
instructions.
2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 47f5f887e8 Fix wrong line number before comment line; fix #4993 2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto c143d87e7c Remove mrb_run from MRB_API; #4488
`mrb_run` requires to push callinfo stack before calling, which is very
hard from outside of `vm.c`. So there should be virtually no correct
usage of the function, hence the cause of #4488. We removed it.

You can use `mrb_top_run(mrb, proc, self, 0)` instead of
`mrb_run(mrb, proc self)`.
2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 2fcdd3f8eb Add assertion as originally intended; ref #4986 2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 8c0dc55af8 Update doc/guides/compile.md to note the bison failure on Mac. 2020-05-07 08:38:46 +09:00
Yukihiro "Matz" Matsumoto 8c04379a4c Merge pull request #4990 from komainu8/enable-method-t-struct-on-32bit-linux
Enable MRB_METHOD_T_STRUCT by default on 32bit GUN/Linux
2020-05-05 22:57:40 +09:00
Horimoto Yasuhiro a5bfe548d7 Enable MRB_METHOD_T_STRUCT by default on 32bit GUN/Linux
Because we can't use the highest 2 bits of function pointers.
2020-05-04 15:34:16 +09:00
Yukihiro "Matz" Matsumoto e77e6e9d12 Fix _read_buf to be more efficient; fix #4982
The bug was introduced by #4712. The `getc' problem resurrected.
It should be addressed soon.
2020-05-01 16:57:45 +09:00
Yukihiro "Matz" Matsumoto a2b87c033a Fix IO#sysread to update buffer string on EOF; ref #4982 2020-05-01 16:54:13 +09:00
Yukihiro "Matz" Matsumoto b3c5d94bd1 Update IO#ungetc to keep @buf string; ref #4982 2020-05-01 16:53:55 +09:00
Yukihiro "Matz" Matsumoto d029549c2f Fix UTF-8 boundary check; ref #4982 2020-05-01 16:53:25 +09:00
Uchio Kondo 6e13467ce8 Fix typo and include location 2020-05-01 16:52:11 +09:00
Uchio Kondo 508ac2030e Skip socket check on windows 2020-05-01 16:51:47 +09:00
Uchio Kondo 4b81bce48d Follow C90 style 2020-05-01 16:51:22 +09:00
Uchio Kondo 3486675e00 Test mruby-io in tmpdir when AF_UNIX cannot be created on cwd 2020-05-01 16:50:54 +09:00
Yukihiro "Matz" Matsumoto 84aad39940 Merge pull request #4987 from shuujii/avoid-changing-directory-in-mruby-io-test
Avoid changing directory in `mruby-io` test
2020-04-30 17:13:11 +09:00
Yukihiro "Matz" Matsumoto c89ca5ebb8 Merge pull request #4988 from shuujii/refine-.travis.yml
Refine `.travis.yml`
2020-04-30 17:12:36 +09:00
KOBAYASHI Shuji 1a4b86233f Refine .travis.yml
* Disable automatic update and clean up on `brew install` (install time
  160 sec -> 5 sec).
* Avoid using deprecated keys.
2020-04-30 13:42:24 +09:00
Yukihiro "Matz" Matsumoto 69a487c407 Merge pull request #4984 from dearblue/break-to_s
Sorting the list of gems at build time by name
2020-04-30 08:38:33 +09:00
Yukihiro "Matz" Matsumoto f32c73ad1f Merge pull request #4986 from dearblue/assert-io
Avoid comparing pointers and integers
2020-04-29 18:34:40 +09:00
Yukihiro "Matz" Matsumoto a343439973 Merge pull request #4985 from dearblue/print-gems
Makes `mrb_any_to_s()` accept an object whose class is `NULL`
2020-04-29 18:34:03 +09:00
KOBAYASHI Shuji aeb86d953e Avoid changing directory in mruby-io test 2020-04-29 17:48:01 +09:00
dearblue 49bba6c997 Avoid comparing pointers and integers 2020-04-29 17:18:09 +09:00
dearblue 49b2e8c3a9 Makes mrb_any_to_s() accept an object whose class is NULL
When using `mrb_any_to_s()` for debugging purposes, giving an object
whose class is `NULL` no longer causes a SIGSEGV and no crash.
This is achieved by making `mrb_class_name()` and `mrb_str_cat_cstr()`
null safe.
2020-04-29 16:59:16 +09:00
dearblue 9c1220e14d Sorting the list of gems at build time by name
Printing them in sorted order makes it easier to find the desired gem.
But it has come to completely ignore the dependency.
2020-04-29 16:55:18 +09:00
Yukihiro "Matz" Matsumoto e2ac2a82a5 Should not use assert with expressions with side-effect; ref #4981
`assert()` can be completely removed when `NDEBUG` is set.
2020-04-28 22:37:14 +09:00
Yukihiro "Matz" Matsumoto bb6290a5d5 Fixed wrong condition in #4981. 2020-04-28 22:34:33 +09:00
Yukihiro "Matz" Matsumoto 312411dea0 Add #include <string.h> on all platforms for strncpy; #4981 2020-04-28 22:34:33 +09:00
Yukihiro "Matz" Matsumoto 7277682cfb Remove unused local variable if MRB_UTF8_STRING is not set.
Ref #4982 #4983
2020-04-28 22:34:01 +09:00
Yukihiro "Matz" Matsumoto 0f229bfbbf Avoid snprintf in mruby-io test; ref #4981 2020-04-28 18:30:50 +09:00
Yukihiro "Matz" Matsumoto 28b23b44ec Remove the temporary file from the AF_UNIX socket test; #4981 2020-04-28 18:13:43 +09:00
Yukihiro "Matz" Matsumoto 8627157298 Fix IO#readchar to return broken UTF-8 rather than EOF error.
The behavior is different from CRuby, but we believe this is a right
behavior for mruby, which only supports either ASCII or UTF-8
exclusively; fix #4983, ref #4982

```
$ printf '\xe3\x81' | ruby -e 'p STDIN.readchar'
"\xE3\x81"
```

```
$ printf '\xe3\x81' | mruby -e 'p STDIN.readchar'
"\xE3"
```
2020-04-28 18:07:17 +09:00
Yukihiro "Matz" Matsumoto b87268f130 Fix IO#readchar to support UTF-8 char reading; fix #4712
This fix only effective when `MRB_UTF8_STRING` is set.
2020-04-28 13:57:46 +09:00
Yukihiro "Matz" Matsumoto a395f8e2c8 Rename (and expose) UTF-8 related functions; ref #4712
- mrb_utf8len() - returns the size of a UTF-8 char (in bytes)
- mrb_utf8_strlen() - returns the length of a UTF-8 string (in char)
2020-04-28 13:57:46 +09:00
Yukihiro "Matz" Matsumoto 3ce459f23a Fix _read_buf to be more efficient; fix #4982
The bug was introduced by #4712. The `getc' problem resurrected.
It should be addressed soon.
2020-04-28 13:57:46 +09:00
Yukihiro "Matz" Matsumoto e51923778f Fix IO#sysread to update buffer string on EOF; ref #4982 2020-04-28 13:57:46 +09:00
Yukihiro "Matz" Matsumoto 468578113a Update IO#ungetc to keep @buf string; ref #4982 2020-04-28 13:57:46 +09:00
Yukihiro "Matz" Matsumoto 2c32154115 Fix UTF-8 boundary check; ref #4982 2020-04-28 13:57:46 +09:00
Yukihiro "Matz" Matsumoto 47d99457d9 Merge pull request #4981 from udzura/fix-test-mruby-io-on-vboxsf
Test mruby-io in tmpdir when AF_UNIX cannot be created on cwd
2020-04-28 09:46:56 +09:00
Uchio Kondo 88b756b39f Fix typo and include location 2020-04-28 01:52:56 +09:00
Uchio Kondo 462ff4cc84 Skip socket check on windows 2020-04-28 01:49:39 +09:00
Uchio Kondo 18274e717a Follow C90 style 2020-04-28 01:45:46 +09:00
Uchio Kondo 7870f74c21 Test mruby-io in tmpdir when AF_UNIX cannot be created on cwd 2020-04-28 01:33:50 +09:00
Yukihiro "Matz" Matsumoto 8dee2e3984 Updating parse.y for recent bison` (retry). 2020-04-27 18:52:43 +09:00
Yukihiro "Matz" Matsumoto 8e86e64d78 Revert "Change obsolete %pure-parser to %define api.pure."
This reverts commit 682a31f92b.
Unfortunately, I couldn't run newer `bison` on TravisCI. Maybe next
time.
2020-04-27 12:27:56 +09:00
Yukihiro "Matz" Matsumoto e79e972255 Update .travis.yml to support newer bison on MacOS.
If it doesn't work, I will revert the last update to `parse.y`.
2020-04-27 12:21:35 +09:00
Yukihiro "Matz" Matsumoto 682a31f92b Change obsolete %pure-parser to %define api.pure.
Recent `bison` warns for `%pure-parser`. We kept it since MacOS only
provide ancient `bison`, but the warning is noisy and there's no hope
that Apple will upgrade `bison`. MacOS users must install the newer
version of `bison`, by typing `brew install bison` for example.

Note that `brew` does not overwrite the `bison` execution path
automatically, so you need to update your `.bash_profile` as instructed
by `brew`.
2020-04-27 09:00:22 +09:00
Yukihiro "Matz" Matsumoto 17974aa285 Merge pull request #4978 from dearblue/test-ensure
Integrate class `EnsureYieldBreak` under test
2020-04-27 09:00:13 +09:00
Yukihiro "Matz" Matsumoto 0a7fd86d59 Merge pull request #4980 from dearblue/context
Reduce `struct mrb_context`
2020-04-27 08:59:19 +09:00
Yukihiro "Matz" Matsumoto d95d46dee6 Merge pull request #4979 from dearblue/mruby-bin
Remove unused `mruby-error` in `mruby-bin-mruby`
2020-04-27 08:56:50 +09:00
dearblue 81c8352179 Integrate class EnsureYieldBreak under test 2020-04-26 21:16:44 +09:00
dearblue 6d80c9505d Remove unused mruby-error in mruby-bin-mruby 2020-04-26 21:16:22 +09:00
dearblue 1b0cf6a91b Reduce struct mrb_context 2020-04-26 21:15:24 +09:00
Yukihiro "Matz" Matsumoto 954ce5379c Implemented argument forwarding by ... 2020-04-25 00:00:22 +09:00
Yukihiro "Matz" Matsumoto 8b5c19218d Merge pull request #4976 from dearblue/splice-undef
Support `undef` for `mrb_ary_splice()` instead of `[]`
2020-04-24 23:36:12 +09:00
Yukihiro "Matz" Matsumoto f6408c7b11 Merge pull request #4975 from dearblue/io-comment
Removed comments mentioning `MRB_WITHOUT_FLOAT`; ref 2e661e8
2020-04-24 23:35:10 +09:00
dearblue 095aae5e2c Removed comments mentioning MRB_WITHOUT_FLOAT; ref 2e661e8
The comment is for messages when `MRB_INT16` and `MRB_WITHOUT_FLOAT` are
specified at the same time.
The comment itself is no longer needed now that `MRB_INT16` is gone.
2020-04-24 21:47:20 +09:00
dearblue 26eb29547b Support undef for mrb_ary_splice() instead of []
When removing elements from an array, it is possible to avoid creating
an empty array.

Before this patch:

```c
mrb_ary_splice(mrb, ary, head, len, mrb_ary_new(mrb));
```

After this patch:

```c
mrb_ary_splice(mrb, ary, head, len, mrb_undef_value());
```
2020-04-24 21:32:35 +09:00
Yukihiro "Matz" Matsumoto d3a02a297f Fix instance_exec and class_exec to avoid crash on indirect calls.
Thank you @shuujii to additional report on #4973
2020-04-22 16:48:33 +09:00
Yukihiro "Matz" Matsumoto ab508e1e7f Make mrb_obj_instance_eval to use mrb_singleton_class_ptr; #4973 2020-04-22 16:47:26 +09:00
Yukihiro "Matz" Matsumoto 87d1bbe947 Add new function mrb_singleton_class_ptr(); ref #4973
The difference between `mrb_singleton_class` and `mrb_singleton_class_ptr`:

- `mrb_singleton_class_ptr` returns `struct RClass*`.
- `mrb_singleton_class_ptr` returns `NULL` on immediate values where
  `mrb_singleton_class` raises exceptions.
2020-04-22 16:44:39 +09:00
Yukihiro "Matz" Matsumoto 2e661e82d1 Removed comments mentioning MRB_INT16. 2020-04-21 20:47:22 +09:00
Yukihiro "Matz" Matsumoto 61c6832b48 Fix the bug by #instance_eval called via a method object; fix #4973
The tranpoline code in 6a0b68f8b was wrong; reverted.
2020-04-21 15:44:21 +09:00
Yukihiro "Matz" Matsumoto ed0038fdf2 Simplified mrb_obj_instance_eval; ref #4973 2020-04-21 15:43:35 +09:00
Yukihiro "Matz" Matsumoto c181d89c9d Kernel#clone and Kernel#dup no longer raise TypeError; fix #4974
In ISO, those methods should raise `TypeError`, but the spec has been
changed.  The change was discussed in [Feature#12979].
2020-04-21 13:21:12 +09:00
Yukihiro "Matz" Matsumoto c91c9e2429 Merge pull request #4968 from dearblue/check-fd
Check the file descriptor with `IO#initialize`; resolve #4966
2020-04-15 09:58:20 +09:00
Yukihiro "Matz" Matsumoto 7add524041 Selecting fd should be less than FD_SETSIZE; close #4966 2020-04-14 14:51:22 +09:00
Yukihiro "Matz" Matsumoto 72928f201c Merge pull request #4972 from dearblue/boxnan-cptr
Fix `MRB_TT_CPTR` object with `MRB_NAN_BOXING`
2020-04-14 14:51:00 +09:00
Yukihiro "Matz" Matsumoto 81a9210091 Merge pull request #4969 from dearblue/nostdio-pack
Support `MRB_DISABLE_STDIO` for mruby-pack; ref #4954
2020-04-14 14:46:25 +09:00
Yukihiro "Matz" Matsumoto e9877bc72a Merge pull request #4970 from dearblue/nostdio-sprintf
Support `MRB_DISABLE_STDIO` for mruby-sprintf; ref #4954
2020-04-14 14:45:26 +09:00
Yukihiro "Matz" Matsumoto ea632ab8a4 Merge pull request #4971 from dearblue/mruby-config
Fixed a build error in mruby-config
2020-04-14 09:29:00 +09:00
dearblue d0501c69b0 Fix MRB_TT_CPTR object with MRB_NAN_BOXING
Previously, if `MRB_NAN_BOXING` is defined, for example,
`mrb_cptr_value()` could not keep an odd address.

If it is `MRB_32BIT`, it can be embedded in `NaN` as it is.

If it is `MRB_64BIT`, some operations are shared with `MRB_WORD_BOXING`.
In this case, the MRB_API function `mrb_nan_boxing_cptr_value()` is
defined.
2020-04-13 23:12:09 +09:00
dearblue 3c03385e2e Check the file descriptor with IO#initialize; resolve #4966 2020-04-12 14:18:36 +09:00
dearblue 191ccbf660 Support MRB_DISABLE_STDIO for mruby-sprintf; ref #4954 2020-04-11 22:11:24 +09:00
dearblue d983269908 Add mrb_float_to_cstr() MRB_API function
In order to share the same operation with `mrb_float_to_str()`,
the internal structure is modified.
2020-04-11 22:11:24 +09:00
dearblue 2ceab2d270 Supports some specifier flags with mrb_float_to_str()
Changed to understand `#`, `0`, `-`, ` ` and `+`.

Based on src/stdio/vfprintf.c in git://git.musl-libc.org/musl
2020-04-11 22:11:10 +09:00
dearblue 8ce3664305 Supports width specifier with mrb_float_to_str()
Based on src/stdio/vfprintf.c in git://git.musl-libc.org/musl
2020-04-11 22:10:57 +09:00
dearblue ccd8485111 Add missing MRB_API 2020-04-11 21:59:30 +09:00
dearblue 70caf4ed6d Fixed a build error in mruby-config
The build error occurred when the "build/XXX/bin" directory did not exist.
2020-04-11 15:43:24 +09:00
dearblue b7c8bf7781 Support MRB_DISABLE_STDIO for mruby-pack; ref #4954 2020-04-11 15:29:07 +09:00
Hiroshi Mimaki 3d46f1b620 Update version to 2.1.1. (mruby 2.1.1 RC) 2020-04-10 13:05:23 +09:00
Yukihiro "Matz" Matsumoto 63c7ff341a Merge pull request #4965 from mimaki/remove-cygwin_filename
Merged `cygwin_filename()` into `filename()`.
2020-04-08 22:40:49 +09:00
mimaki a8ab74a6dc Merged cygwin_filename() into filename() because Cygwin pathnames are in UNIX format. 2020-04-08 13:27:14 +09:00
Yukihiro "Matz" Matsumoto 7ab5353f80 Merge pull request #4960 from Reckordp/BuildAndroid
Validate windows by Dir testing
2020-04-05 14:17:09 +09:00
Reckordp d7df30bdd8 Unused library folder 2020-04-04 21:57:13 +07:00
Reckordp d317ee144b Correct naming file from Mingw 2020-04-04 21:56:40 +07:00
Yukihiro "Matz" Matsumoto 3cef380b20 Revert part of #4959
To prevent infinite loop on errors; reported by @shuujii
2020-04-04 11:50:59 +09:00
Reckordp 707933aa8e Helper for link window's library 2020-04-03 20:34:00 +07:00
Yukihiro "Matz" Matsumoto 068b16a352 Merge pull request #4959 from dsisnero/master
build when directories and files have spaces
2020-04-02 13:26:53 +09:00
dsisnero c7ab4cf616 fix for quoting visualcpp 2020-04-01 12:31:48 -06:00
Dominic Sisneros e3875ae8c5 build when directories and files have spaces
Modified the build to quote filenames so that it builds when files have spaces
2020-04-01 11:55:35 -06:00
Yukihiro "Matz" Matsumoto 226fcb4f2a Avoid unnecessary nextc() recursion. 2020-04-01 23:23:07 +09:00
Yukihiro "Matz" Matsumoto d22b72a7cc Merge pull request #4957 from dearblue/excessive-arena
Fix `mrb_funcall_with_block()` uses more GC arena
2020-04-01 15:40:25 +09:00
dearblue 15dec83832 Fix mrb_funcall_with_block() uses more GC arena
If `mrb->jmp` is `NULL` and the function `mrb_funcall_with_block()` is
called, GC Arena is returned from the function with over-used.

- A normal (no global exodus) return will consume two GC Arena's.
- In the event of an exception, five GC Arena are consumed.

This patch reduces consumption in both cases to one.
2020-03-31 23:24:53 +09:00
Yukihiro "Matz" Matsumoto 5acd802d2b Merge pull request #4956 from dearblue/null-local_variables
Fix NULL pointer dereferences in mrb_local_variables; fix #4955
2020-03-31 22:04:18 +09:00
dearblue 9b15860ddb Fix NULL pointer dereferences in mrb_local_variables; fix #4955
However, the behavior of `#call` on the method object of
`local_variables` is not corrected.
2020-03-30 23:52:59 +09:00
Yukihiro "Matz" Matsumoto 0dacc9a62a Merge pull request #4954 from dearblue/nostdio
Improve configuration guard
2020-03-08 22:37:22 +09:00
dearblue 67606170e3 Add configuration guard for MRB_DISABLE_STDIO
ref #4576 and ref #4947

* Need MRBAPI functions without `MRB_DISABLE_STDIO`:
  * mrbgems/mruby-bin-debugger
  * mrbgems/mruby-bin-mirb
  * mrbgems/mruby-bin-mrbc
  * mrbgems/mruby-bin-mruby
  * mrbgems/mruby-bin-strip
* Need `stdio.h`:
  * mrbgems/mruby-io
  * mrbgems/mruby-print
* Need `snprintf()` in `stdio.h`:
  * mrbgems/mruby-pack
  * mrbgems/mruby-sprintf
2020-03-08 21:57:17 +09:00
dearblue cc1db2d117 Remove unnecessary 'stdio.h'; ref #4947
'stdio.h' is included in 'mruby.h' ('mrbconf.h').

However, keep 'stdio.h' used by mruby-test.
2020-03-08 21:42:09 +09:00
dearblue b3d4ab0cd8 Improve conflict error message of mruby-bin-debugger; ref 87d1b2a91 2020-03-08 20:49:22 +09:00
Yukihiro "Matz" Matsumoto 5bf5a2cc6e Merge pull request #4953 from Reckordp/BuildAndroid
Some rule to CrossBuild Android
2020-03-08 19:07:32 +09:00
Yukihiro "Matz" Matsumoto e15e6e761e Merge branch 'master' into BuildAndroid 2020-03-08 19:01:29 +09:00
Yukihiro "Matz" Matsumoto 1cc270f0cc Small refactoring on #4952
Fix the argument of `mrb_file_is_absolute_path()`.
2020-03-08 18:57:49 +09:00
Yukihiro "Matz" Matsumoto 55f3202650 Merge pull request #4952 from Reckordp/master
Traditional, UNC, and Drive Path
2020-03-08 18:52:24 +09:00
Reckordp a8d508c567 Let me in Please 2020-03-08 14:41:38 +07:00
Reckordp 7c85a1ff07 Increase flexibility of CrossBuild 2020-03-08 14:23:55 +07:00
Reckordp dd6f5e4607 Let me in Please 2020-03-08 11:50:26 +07:00
Reckordp ab1465d9d5 Traditional, UNC, and Device Is Absolute? 2020-03-08 10:53:18 +07:00
Reckordp 66c44b8568 Commit from remote 2020-03-08 05:40:47 +07:00
Reckordp 6ee24fe1bc Evaluate all type path 2020-03-08 05:32:27 +07:00
Yukihiro "Matz" Matsumoto 4398bae56a Merge branch 'dearblue-io-pread-pwrite' 2020-03-07 19:07:13 +09:00
Yukihiro "Matz" Matsumoto 20f9128f73 Small refactoring on #4939 2020-03-07 19:06:46 +09:00
Yukihiro "Matz" Matsumoto 6901752723 Use in-house macro ISALPHA instead of isalpha; ref #4950 2020-03-07 19:03:45 +09:00
Yukihiro "Matz" Matsumoto 886355007c Merge branch 'io-pread-pwrite' of https://github.com/dearblue/mruby into dearblue-io-pread-pwrite 2020-03-07 19:00:30 +09:00
Yukihiro "Matz" Matsumoto f45549edbf Merge pull request #4951 from Reckordp/master
Fix unfinished changes
2020-03-07 17:58:26 +09:00
Reckordp 5a4b9fd877 Add absolute path for UNC 2020-03-07 15:50:14 +07:00
Reckordp f319c5fb26 Fix typo 2020-03-07 15:18:48 +07:00
Yukihiro "Matz" Matsumoto 4687f8790c Merge the update suggested by @mattn; ref #4950 2020-03-07 14:58:05 +09:00
Yukihiro "Matz" Matsumoto 30eaee30fa Merge pull request #4950 from Reckordp/master
Absolute path for windows
2020-03-07 14:53:37 +09:00
Reckordp 8df49ea955 Absolute path for windows 2020-03-07 09:09:28 +07:00
Yukihiro "Matz" Matsumoto 7905431fe9 Merge pull request #4948 from kou/32bit-windows-method-t-struct
Enable MRB_METHOD_T_STRUCT by default on 32bit Windows
2020-03-04 21:25:10 +09:00
Sutou Kouhei 96d727177e Enable MRB_METHOD_T_STRUCT by default on 32bit Windows
Because we can't use the highest 2 bits of function pointers.
2020-03-04 18:35:40 +09:00
Yukihiro "Matz" Matsumoto be86bd3c49 Merge pull request #4946 from sizious/sega-dreamcast-example
Improving comments in the cross-compiling sample for the Sega Dreamcast.
2020-02-23 18:01:05 +09:00
SiZiOUS 260dc6d741 Improving comments in the cross-compiling example for the Sega Dreamcast (sh-elf). 2020-02-22 23:44:13 +01:00
Yukihiro "Matz" Matsumoto 3ba32e80af Merge pull request #4945 from Leo-Neat/master
Add CIFuzz action
2020-02-22 14:09:23 +09:00
Yukihiro "Matz" Matsumoto ac5ec1a153 Merge pull request #4944 from sizious/sega-dreamcast-example
Added example for cross-compiling for Sega Dreamcast (sh-elf).
2020-02-22 14:07:46 +09:00
Yukihiro "Matz" Matsumoto 34be5acc99 Merge pull request #4942 from inobelar/patch-1
Updated README.md - Fixed link to github issues
2020-02-22 13:25:11 +09:00
Leo Neat 4713502083 CIFuzz action 2020-02-21 15:27:53 -08:00
SiZiOUS 2f6afb52a9 Added example for cross-compiling for Sega Dreamcast (sh-elf).
Thanks to @yujiyokoo for demonstrating mruby usage on Sega Dreamcast at RubyConf AU 2020!
See more here: https://youtu.be/ni-1x5Esa_o
2020-02-21 22:07:07 +01:00
Yurii Nakonechnyi 20597b6d36 Updated README.md - Fixed link to github issues 2020-02-21 16:57:19 +02:00
Yukihiro "Matz" Matsumoto 0301d8a89b Fix integer boundary check before float to time_t casting. 2020-02-12 11:54:32 +09:00
Yukihiro "Matz" Matsumoto 736ea1f5c7 Merge pull request #4941 from davidsiaw/mac-compat
Include time.h for ios
2020-02-05 23:11:45 +09:00
Yukihiro "Matz" Matsumoto ffb55e51f1 Add explicit type cast to return value from mrmchr; ref #4940
C++ is stricter in implicit type casting.
2020-02-03 12:59:29 +09:00
Yukihiro "Matz" Matsumoto 6d9109bf70 Use simple search for short strings in mrb_memsearch_qs; close #4940
Differences from the PR #4940:
* Use simple search for short strings only.
* "short" means `m+n` is shorter than `MRB_QS_SHORT_STRING_LENGTH`.
* The current default value for `MRB_QS_SHORT_STRING_LENGTH` is 2048.
2020-02-03 12:59:29 +09:00
dearblue 4c6d524c47 Implement IO#pread and IO#pwrite
It is available by default in environments where `__unix__` is defined.
Other environments are enabled by defining `MRB_WITH_IO_PREAD_PWRITE`
(requires an implementation of `pread()` and `pwrite()` functions).

In any case, you can disable it by defining
`MRB_WITHOUT_IO_PREAD_PWRITE`.
2020-02-02 21:20:25 +09:00
Yukihiro "Matz" Matsumoto 3c67d9b1c0 Merge pull request #4938 from dearblue/socket-mingw
Fix builds for old mingw in mruby-socket; ref #4914
2020-02-01 17:41:19 +09:00
dearblue 8020374d6b Fix builds for old mingw in mruby-socket; ref #4914 2020-02-01 15:58:32 +09:00
Yukihiro "Matz" Matsumoto db64bd42d3 Add explicit casting in file.c to silence warnings. 2020-01-31 09:26:45 +09:00
Yukihiro "Matz" Matsumoto 724c90f369 Avoid casting warning from mrb_int to int in io.c. 2020-01-31 09:26:05 +09:00
Yukihiro "Matz" Matsumoto c0a6439a69 Avoid implicit integer casting in backtrace.c and hash.c. 2020-01-31 09:25:10 +09:00
Yukihiro "Matz" Matsumoto 10c2b7ee1c Remove unnecessary use of uint16_t in symbol.c. 2020-01-31 09:22:27 +09:00
Yukihiro "Matz" Matsumoto f34623fb03 Fix arena index type from mrb_int to just int. 2020-01-30 17:35:50 +09:00
Yukihiro "Matz" Matsumoto c8f4d72302 Move fallback definitions of FLT_EPSILON etc. after #include <mruby/value.h>
that includes `float.h`. It allows definitions from native headers.
2020-01-30 17:16:12 +09:00
Yukihiro "Matz" Matsumoto 7771c215e4 Removed junk.
My cat stepped on the keyboard at the last moment before the commit.
2020-01-29 10:23:31 +09:00
Yukihiro "Matz" Matsumoto ff5d1914ab Remove unused local variable mid; ref #4936 2020-01-29 08:56:05 +09:00
Yukihiro "Matz" Matsumoto e7e999414c Merge pull request #4873 from dearblue/open-flags
Support bit flags for `IO.open`
2020-01-28 11:09:33 +09:00
David Siaw 36efc33650 include time.h for ios 2020-01-28 00:43:49 +08:00
Yukihiro "Matz" Matsumoto 364c47610f Fixed backtrace message for top-level blocks; fix #4936
In top-level, `mid` is `NULL`. We used to ignore 'mid` update for `NULL`.
2020-01-27 14:34:54 +09:00
Yukihiro "Matz" Matsumoto 59464f3528 Merge pull request #4935 from mimaki/delete-duplicated-Array-delete_if
Delete duplicated `Array#delete_if`.
2020-01-21 13:40:30 +09:00
Hiroshi Mimaki 7d9a49efab Delete duplicated Array#delete_if test. 2020-01-21 12:50:26 +09:00
Hiroshi Mimaki e24b4a1e19 Delete duplicated Array#delete_if. 2020-01-21 11:35:53 +09:00
Yukihiro "Matz" Matsumoto f7abda1437 Remove debug target from travis_config.rb. 2020-01-15 23:39:19 +09:00
Yukihiro "Matz" Matsumoto ff57c0278f Remove broken MRB_INT16 configuration option. 2020-01-15 21:32:00 +09:00
Yukihiro "Matz" Matsumoto 2742ded32f Fixed wrong condition in #4926 fix. 2020-01-10 23:05:27 +09:00
Yukihiro "Matz" Matsumoto 70e5746896 Fixed wrong condition for copying arguments on stack; fix #4926
This bug was introduced in 694089f to address #4832
2020-01-10 17:58:15 +09:00
Yukihiro "Matz" Matsumoto fc8fb41451 Small refactoring in hash_slice; ref #4926 2020-01-10 17:57:33 +09:00
Yukihiro "Matz" Matsumoto dc86e35cac Add MRB_WITHOUT_FLOAT guard to <math.h>. 2020-01-08 10:53:11 +09:00
Yukihiro "Matz" Matsumoto 2124b9b4c9 Fix buffer overflow in mrb_str_len_to_dbl.
Issue 19902: mruby:mruby_fuzzer: Stack-buffer-overflow in mrb_str_len_to_dbl
2020-01-08 10:52:24 +09:00
Yukihiro "Matz" Matsumoto dbba0ca517 p->locals may be NULL when error occurs before the point.
This is reported by oss-fuzz:
Issue 19886: mruby:mruby_fuzzer: Potential-null-reference in setup_numparams
2020-01-08 01:18:53 +09:00
Yukihiro "Matz" Matsumoto afad939173 Check memory boundary in mrb_str_len_to_dbl. 2020-01-07 08:58:06 +09:00
Yukihiro "Matz" Matsumoto 3e4e10ffb6 "0x10".to_f should be 0, not 16.0; fix #4924 2020-01-06 22:27:39 +09:00
Yukihiro "Matz" Matsumoto c60bccaa94 Check remaining string length before access to avoid OOB access. 2020-01-06 22:25:47 +09:00
Yukihiro "Matz" Matsumoto 59756aef14 Need to preserve the original input string in mrb_str_len_to_dbl. 2020-01-06 22:25:05 +09:00
Yukihiro "Matz" Matsumoto 874797f36f Merge branch 'dearblue-file-size-truncate' 2020-01-06 18:58:42 +09:00
Yukihiro "Matz" Matsumoto b545f62aeb Avoid Boxing/Unboxing of file descriptors; ref #4872 2020-01-06 18:57:43 +09:00
Yukihiro "Matz" Matsumoto ca71eb7eef Merge branch 'file-size-truncate' of https://github.com/dearblue/mruby into dearblue-file-size-truncate 2020-01-06 18:49:52 +09:00
Yukihiro "Matz" Matsumoto ccf28775b8 Fix mrb_str_len_to_dbl to support Hexadecimal like 0x10. 2020-01-06 15:52:39 +09:00
Yukihiro "Matz" Matsumoto 2532e625ed Refactor mrb_cstr_to_dbl; ref #4920 2020-01-06 15:52:39 +09:00
Yukihiro "Matz" Matsumoto 111045ecad Avoid creating temporary objects in read_irep_record_1; close #4920
The basic idea of this change is from @dearblue.

Note: the arguments of `mrb_str_pool()` have changed, but the function
is provided for internal use (No `MRB_API`). So basically you don't have
to worry about the change.
2020-01-06 15:52:39 +09:00
Yukihiro "Matz" Matsumoto 282f907f1b Merge pull request #4923 from dearblue/kwargs-block
Fix ainfo with keyword arguments; fix #4921
2020-01-05 20:59:18 +09:00
dearblue 541185ef14 Fix ainfo with keyword arguments; fix #4921 2020-01-05 16:48:34 +09:00
Yukihiro "Matz" Matsumoto d82e91898d Merge pull request #4917 from dearblue/va_end
Call `va_end()` before return
2020-01-02 09:26:15 +09:00
dearblue 00f5c92149 Call va_end() before return
The behavior when returning from a function without `va_end()` is
undefined.
2020-01-02 00:58:27 +09:00
Yukihiro "Matz" Matsumoto 9174b18f34 Rename mrb_num_args_error to mrb_argnum_error; ref #4863 2020-01-01 22:37:14 +09:00
Yukihiro "Matz" Matsumoto b9c78c3fcc Merge pull request #4863 from shuujii/add-mrb_num_args_error-for-wrong-number-of-arguments-error
Add `mrb_num_args_error()` for "wrong number of arguments" error
2020-01-01 22:34:22 +09:00
Yukihiro "Matz" Matsumoto 021f228f9d Merge pull request #4919 from shuujii/revert-SHARED-string-is-not-required-when-sharing-POOL-string
Revert "SHARED string is not required when sharing POOL string" (75949836)
2020-01-01 22:32:41 +09:00
KOBAYASHI Shuji 40b8490fa4 Revert "SHARED string is not required when sharing POOL string" (75949836)
Because literal pool may be released by GC.

#### Example:

  ```ruby
  s1 = eval('"abcdefghijklmnopqrstuvwxyz01"')
  GC.start
  p s1  #=> "\x00\x00\x00\x00\x00\x00\x00\x90\x00\x00\x00\x00\x00\x00\x00\x90\x03\x00stuvwxyz01"
  ```
2020-01-01 19:16:05 +09:00
Yukihiro "Matz" Matsumoto 7247e4cf1b Merge pull request #4918 from dearblue/sync-vars
Integrate `i` and `arg_i` in `mrb_get_args()`
2020-01-01 15:31:16 +09:00
Yukihiro "Matz" Matsumoto b49bc17f48 Merge pull request #4916 from dearblue/stdint
Do not include `stdint.h` before `mruby.h`; ref #4750
2020-01-01 15:30:29 +09:00
dearblue 7ed26ead9b Integrate i and arg_i in mrb_get_args()
The behavior of these two variables is the same.
2020-01-01 15:07:16 +09:00
dearblue 20d3882469 Do not include stdint.h before mruby.h; ref #4750 2020-01-01 14:17:11 +09:00
Yukihiro "Matz" Matsumoto fd1cff7735 Fixed wrong usages of mrb_get_args in vformat.c. 2020-01-01 12:34:30 +09:00
Yukihiro "Matz" Matsumoto 943fbb2bea Allow here-doc in the middle of Hash expressions; fix #4815 2020-01-01 12:21:17 +09:00
Yukihiro "Matz" Matsumoto 28c8e29c4d Merge pull request #4915 from shuujii/silence-GCC-warning-in-time.c-on-Travis-CI
Silence GCC warning in `time.c` on Travis CI
2019-12-31 22:36:41 +09:00
KOBAYASHI Shuji b493229a23 Silence GCC warning in time.c on Travis CI
Silence the following warnings:

  ```
  /mruby/mrbgems/mruby-time/src/time.c:260:55: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    if ((MRB_INT_MAX > MRB_TIME_MAX && i > 0 && i > MRB_TIME_MAX) ||
                                                  ^
  ```
2019-12-31 21:52:20 +09:00
Yukihiro "Matz" Matsumoto 83e502b847 Merge pull request #4914 from dearblue/fix-4869
Fix builds for modern mingw; fix #4869
2019-12-31 09:42:47 +09:00
dearblue 93d0e5d9fb Fix builds for modern mingw; fix #4869
What I intended to fix in #4869 was a patch for an old MinGW.
Recent MinGWs have their own `mkstemp()` function.
I knew this after checking the patch #4903.
2019-12-31 00:11:40 +09:00
Yukihiro "Matz" Matsumoto 5e519cdbb5 Merge pull request #4913 from shuujii/use-rake-instead-of-minirake-in-.gitlab-ci.yml
Use `rake` instead of `minirake` in `.gitlab-ci.yml`
2019-12-30 22:24:08 +09:00
KOBAYASHI Shuji b96fa664b0 Use rake instead of minirake in .gitlab-ci.yml
There was an error in the `.gitlab-ci.yml` generation script, so it was also
fixed.
2019-12-30 17:46:22 +09:00
Yukihiro "Matz" Matsumoto 4327f36940 Merge pull request #4912 from shuujii/avoid-unneeded-directory-creation-during-rake--T-etc
Avoid unneeded directory creation during `rake -T`, etc.
2019-12-29 21:08:49 +09:00
KOBAYASHI Shuji b97ebf2aeb Avoid unneeded directory creation during rake -T, etc. 2019-12-29 17:46:55 +09:00
Yukihiro "Matz" Matsumoto e9de5a7a5c Merge pull request #4911 from shuujii/use-Rake.verbose-instead-of-verbose-and-pp_show
Use `Rake.verbose` instead of `$verbose` and `$pp_show` in build scripts
2019-12-28 17:43:54 +09:00
KOBAYASHI Shuji bb98fd78c3 Use Rake.verbose instead of $verbose and $pp_show in build scripts
The incompatibility that the commands of `FileUtils` origin output verbose
by default due to the changes in d8a5163b and 26e6e75b is also fixed.
2019-12-28 17:03:37 +09:00
Yukihiro "Matz" Matsumoto d2f34a8455 Merge pull request #4910 from shuujii/use-Rake-DSL-instead-of-commands-of-FileUtils
Use Rake DSL instead of commands of `FileUtils`
2019-12-27 18:35:19 +09:00
KOBAYASHI Shuji 26e6e75ba6 Use Rake DSL instead of commands of FileUtils
- Respect `--verbose(-v)` and `--dry-run(-n)` options.
- Silence warnings to keyword arguments on Ruby 2.7.
2019-12-27 16:49:32 +09:00
Yukihiro "Matz" Matsumoto 03244b52a0 Revert "Enable sanitizer in travis test"; ref #4864
`gcc` sanitizer does not work on some environment (namely my localhost).
Although it works on Travis, it is not convenient that tests fail on the
local host. We keep sanitizer tests on the local (using `clang`).

This reverts commit 9cde967321.
2019-12-27 11:16:37 +09:00
Yukihiro "Matz" Matsumoto d15e56dab0 Prohibit assignment to numbered parameters.
It is stricter than CRuby but confusing anyway.
2019-12-27 11:05:56 +09:00
Yukihiro "Matz" Matsumoto ff16331754 Allow non numbered-parameter identifier like _1 outside of blocks.
But it causes warnings as CRuby does; fix #4892 fix #489
2019-12-27 11:05:56 +09:00
Yukihiro "Matz" Matsumoto d8a5163b24 Support -v flag of rake; close #4887
The patch was originally written by @take-cheese. I have fixed the
conflict caused by `minirake` deletion - @matz.
2019-12-27 11:05:56 +09:00
Yukihiro "Matz" Matsumoto ed8491cde6 Numbered parameters: usually linked list uses cdr for links. 2019-12-27 11:05:56 +09:00
Yukihiro "Matz" Matsumoto 7e6355975e Prohibit numbered parameters as method arguments; fix #4892
As of CRuby2.7 it is only warned. `mruby` prohibits explicitly to
implement the future Ruby3 behavior.
2019-12-27 11:05:56 +09:00
KOBAYASHI Shuji 716102fff3 Enable MRB_GC_STRESS test on CI
The `debug` build target (`MRB_GC_STRESS` is enabled) on CI have been
compiled but not tested so far. However, I think testing with
`MRB_GC_STRESS` is effective (in fact, I found #4907 bug).

Therefore, I integrated `debug` and `full-debug` build targets to enable
`MRB_GC_STRESS` testing. Testing with `MRB_GC_STRESS` takes a little time,
but compiling takes more time, so CI execution time does not increase due to
decrease of build target.
2019-12-27 11:05:56 +09:00
Yukihiro "Matz" Matsumoto ef6805f599 Merge pull request #4864 from take-cheeze/enable_sanitizer_travis
Enable sanitizer in travis test
2019-12-27 10:58:24 +09:00
Yukihiro "Matz" Matsumoto d6b898685f Merge pull request #4907 from shuujii/fix-poteltially-use-of-wrong-method-cache
Fix potentially use of wrong method cache
2019-12-25 23:23:00 +09:00
KOBAYASHI Shuji 0b2d54f4f1 Fix potentially use of wrong method cache
#### Example (with `MRB_METHOD_CACHE`)

  ```ruby
  GC.start
  c = Class.new
  p c            #=> #<Class:0x7fd6a180e790>
  c.new          #=> cache `c.new`
  c = nil
  GC.start       #=> `c` is GCed
  r = Range.dup
  p r            #=> #<Class:0x7fd6a180e790>
                 #   [same pointer as `c`]
  r.new(2, 3)    #=> ArgumentError: 'initialize':
                 #   wrong number of arguments (2 for 0)
                 #   [`c.new` is called instead of `r.new`]
  ```

#### Cause

  An entry of method cache is identified by class pointer and method
  id. However, reusing memory after GC may create a class with the same
  pointer as the cached class.

#### Treatment

  Cleared method caches of the class when the class is GCed.
2019-12-25 21:31:10 +09:00
Yukihiro "Matz" Matsumoto d4cbe6271c Merge pull request #4906 from shuujii/refine-the-assertion-failure-message-in-mrdb-print-tests
Refine the assertion failure message in mrdb print tests
2019-12-25 10:58:04 +09:00
KOBAYASHI Shuji f92867a59e Refine the assertion failure message in mrdb print tests
#### Before this patch:

  ```console
  Fail: mruby-bin-debugger(print) error (mrbgems: mruby-bin-debugger)
   - Assertion[2]
      Expected true to be false.
  ```

#### After this patch:

  ```console
  Fail: mruby-bin-debugger(print) error (mrbgems: mruby-bin-debugger)
   - Assertion[2]
      Expected "$2 = undefined method 'bar' (NoMethodError)\n" to be start_with? "$2 = (eval):2: undefined method".
  ```
2019-12-24 23:20:20 +09:00
Yukihiro "Matz" Matsumoto d062528653 Merge pull request #4905 from kishima/cygwin_compile
Add double quotes for cygwin filenames #4904
2019-12-24 14:23:24 +09:00
kishima b63f1912df add double quotes for cygwin filenames #4904 2019-12-23 23:36:59 +09:00
Yukihiro "Matz" Matsumoto 18248cfd00 Merge pull request #4901 from take-cheeze/gnu_cxx
Use GNU extension in C++ for cygwin
2019-12-23 21:32:26 +09:00
Yukihiro "Matz" Matsumoto 0f89a91607 Merge pull request #4902 from take-cheeze/native_crlf
Handle CR LF newline natively in lexer
2019-12-23 21:31:51 +09:00
take-cheeze bb0aec1d94 Use binary mode in mrbc source code reading 2019-12-23 21:01:42 +09:00
take-cheeze 10e9f193ca Handle CR LF newline natively in lexer 2019-12-23 21:01:11 +09:00
take-cheeze 38fdca82c6 Use GNU extension in C++ for cygwin 2019-12-23 20:58:43 +09:00
Yukihiro "Matz" Matsumoto 49301ed785 Merge pull request #4900 from shuujii/parallelize-compilation-only-on-Travis-CI
Parallelize compilation only on Travis CI
2019-12-23 20:37:25 +09:00
KOBAYASHI Shuji 212d12f269 Parallelize compilation only on Travis CI
Parallel execution of tests makes log difficult to see due to mixing.
2019-12-23 20:04:11 +09:00
Yukihiro "Matz" Matsumoto a562a9aa93 Merge pull request #4899 from dearblue/build-git
Use `git checkout` instead of `git reset`
2019-12-22 22:31:33 +09:00
dearblue f08d9b288d Use git checkout instead of git reset
With this change, if the checkout fails, it will stop with an error.

The purpose is to avoid deleting working branch history when
developing gem.
2019-12-22 15:09:29 +09:00
dearblue dc15c2838f Display directory with git command 2019-12-22 14:26:00 +09:00
Yukihiro "Matz" Matsumoto 0bd3a67dea Merge pull request #4898 from shuujii/refine-.travis.yml
Refine `.travis.yml`
2019-12-22 13:13:49 +09:00
Yukihiro "Matz" Matsumoto 572958ece3 Merge pull request #4896 from shuujii/fix-undefined-method-Pathname
Fix "undefined method `Pathname'"; fix #4895
2019-12-22 13:12:59 +09:00
Yukihiro "Matz" Matsumoto fa90bcb9ab Merge pull request #4897 from shuujii/use-exec-instead-of-system-in-minirake-for-exit-status
Use `exec` instead of `system` in `minirake` for exit status
2019-12-22 13:11:23 +09:00
KOBAYASHI Shuji 5974d53ab0 Refine .travis.yml
* Use `rake` instead of `minirake`.
* Remove `gperf` configuration.

Execution time seems to be reduced by about 15%.
2019-12-22 11:48:04 +09:00
KOBAYASHI Shuji 66349bcef1 Use exec instead of system in minirake for exit status
#### Before this patch:

  ```console
  $ ./minirake --foo; echo $?
  invalid option: --foo
  0
  ```

#### After this patch:

  ```console
  $ ./minirake --foo; echo $?
  invalid option: --foo
  1
  ```
2019-12-21 23:44:33 +09:00
KOBAYASHI Shuji 9f1167f7c9 Fix "undefined method `Pathname'"; fix #4895 2019-12-21 23:31:17 +09:00
Yukihiro "Matz" Matsumoto 089bb6acad Merge pull request #4888 from dearblue/shellquote
Perform `shellquote` on referenced string
2019-12-21 22:46:27 +09:00
Yukihiro "Matz" Matsumoto 06e09fc7a9 Numbered parameters should not be available in the lambda bodies.
`mruby` does not warn like `CRuby` for cases like #4893.
Fix #4890, fix #4891, fix #4893.
2019-12-21 22:41:32 +09:00
Yukihiro "Matz" Matsumoto 2fe78a0c7c Add emulating minirake that calls real rake. 2019-12-21 22:11:08 +09:00
Yukihiro "Matz" Matsumoto de17f63b45 Abandon minirake. Use rake for compilation; fix #4884 2019-12-21 22:11:08 +09:00
Yukihiro "Matz" Matsumoto fee3c1c242 Merge pull request #4889 from shuujii/_0-is-not-numbered-parameter
`_0` is not numbered parameter
2019-12-21 22:10:42 +09:00
KOBAYASHI Shuji 74f564b0bb _0 is not numbered parameter
#### Before this patch:

  ```console
  $ bin/mruby rb -e '_0=:l; p ->{_0}.()'
  -e:1:13: _0 is not available
  -e:1:13: syntax error, unexpected $end, expecting '}'
  ```

#### After this patch (same as Ruby):

  ```console
  $ bin/mruby rb -e '_0=:l; p ->{_0}.()'
  :l
  ```
2019-12-21 18:54:15 +09:00
dearblue acef52c35e Perform shellquote on referenced string 2019-12-21 17:25:22 +09:00
Yukihiro "Matz" Matsumoto 5cc595cb2a Fix SEGV from numbered parameters outside of blocks; fix #4862 2019-12-21 01:24:56 +09:00
Yukihiro "Matz" Matsumoto ef8621cb61 Merge pull request #4885 from shuujii/fix-potentially-crash-in-%n-of-mrb_vformat-with-64-bit-int
Fix potentially crash in `%n` of `mrb_vformat()` with 64-bit `int`
2019-12-21 01:18:09 +09:00
KOBAYASHI Shuji e8299a89da Fix potentially crash in %n of mrb_vformat() with 64-bit int
If `mrb_sym` is smaller than `int`, it is promoted to `int`.
2019-12-20 23:04:46 +09:00
Yukihiro "Matz" Matsumoto 19fa77ddbb Merge pull request #4871 from dearblue/method-in-method
Avoid method in method
2019-12-20 19:29:48 +09:00
Yukihiro "Matz" Matsumoto adf358363c Merge pull request #4870 from dearblue/unnessesary-branch
Remove unnessesary branches
2019-12-20 19:24:45 +09:00
Yukihiro "Matz" Matsumoto 64e9f278b3 Merge pull request #4874 from dearblue/method-list
Fix for `#methods` to include methods that were `undef`
2019-12-20 19:23:13 +09:00
take-cheeze 9cde967321 Enable sanitizer in travis test 2019-12-19 14:21:49 +09:00
Yukihiro "Matz" Matsumoto 87809742f5 Fix mixed declarations in 429f6de 2019-12-19 10:00:33 +09:00
Yukihiro "Matz" Matsumoto fcde80a4d0 Merge pull request #4881 from shuujii/fix-mruby-bin-debugger-tests
Fix `mruby-bin-debugger` tests; ref d2f2f9db
2019-12-19 09:51:31 +09:00
Yukihiro "Matz" Matsumoto 868ba8464e Merge pull request #4882 from shuujii/simplify-print_backtrace
Simplify `print_backtrace()`
2019-12-19 09:50:22 +09:00
Yukihiro "Matz" Matsumoto 429f6defdd Reimplement vformat tests; close #4868
Avoid creating `Data` object that refers `mruby` objects.
Also close #4622 ref #4613
2019-12-19 09:35:51 +09:00
Yukihiro "Matz" Matsumoto 7f0e1fc90b Revert "%C value need not to be saved in TestVFormat::Native; close #4868"
This reverts commit f507ff4842.
It makes AppVeyor tests fail.
2019-12-19 00:07:08 +09:00
KOBAYASHI Shuji 6df6bd4ac7 Simplify print_backtrace() 2019-12-18 19:35:24 +09:00
KOBAYASHI Shuji f0b8c9ec06 Fix mruby-bin-debugger tests; ref d2f2f9db 2019-12-18 19:34:11 +09:00
Yukihiro "Matz" Matsumoto 815e0c400a Merge pull request #4875 from shuujii/remove-location-info-from-Exception-inspect
Remove location info from `Exception#inspect`
2019-12-18 01:55:23 +09:00
Yukihiro "Matz" Matsumoto 4c1667a5f6 Merge pull request #4879 from shuujii/refine-output-of-mrb_print_error
Refine output of `mrb_print_error()`
2019-12-18 01:54:28 +09:00
Yukihiro "Matz" Matsumoto f507ff4842 %C value need not to be saved in TestVFormat::Native; close #4868 2019-12-18 01:40:11 +09:00
KOBAYASHI Shuji 29ecc3840a Refine output of mrb_print_error()
The following improvements are made according to Ruby's behavior:

- Match location number to index.
- Remove duplicate most recent call output.
- Fix that first call is not output when array (unpacked) backtrace.

### Example

  ```ruby
  def a; raise "error!" end
  def b; a end
  begin
    b
  rescue => e
    e.backtrace if ARGV[0] == "unpack"  # unpack backtrace
    raise e
  end
  ```

#### Before this patch:

  ```
  $ bin/mruby example.rb unpack
  trace (most recent call last):
    [0] example.rb:2:in b
    [1] example.rb:1:in a
  example.rb:1: error! (RuntimeError)
  ```

#### After this patch:

  ```
  $ bin/mruby example.rb unpack
  trace (most recent call last):
    [2] example.rb:4
    [1] example.rb:2:in b
  example.rb:1:in a: error! (RuntimeError)
  ```
2019-12-17 23:16:20 +09:00
Yukihiro "Matz" Matsumoto 8bc9a79e65 Merge pull request #4869 from dearblue/mingw32-io-test
Fix mruby-io test for mingw32
2019-12-17 00:49:01 +09:00
Yukihiro "Matz" Matsumoto 6a22fa7f47 Merge pull request #4878 from shuujii/remove-unneeded-null-checks-to-struct-backtrace_locationfilename
Remove unneeded null checks to `struct backtrace_location::filename`
2019-12-17 00:48:27 +09:00
KOBAYASHI Shuji 854c61c3ab Remove unneeded null checks to struct backtrace_location::filename
`struct backtrace_location` is created only in `each_backtrace()`, and
the `filename` field will never be null (it will be `(unknown)` if null).
2019-12-16 18:57:53 +09:00
Yukihiro "Matz" Matsumoto 85b4ed623e Merge pull request #4876 from dearblue/class-methods
Remove module only methods from class
2019-12-16 13:53:55 +09:00
Yukihiro "Matz" Matsumoto fc5a9c2be2 Merge pull request #4877 from shuujii/drop-dependencies-from-mruby-complex-to-some-gems
Drop dependencies from `mruby-complex` to some gems
2019-12-16 13:51:48 +09:00
Yukihiro "Matz" Matsumoto cc6d17423b Merge pull request #4859 from dearblue/authors
Add "mruby developers" into some gems; Resolve #4709
2019-12-16 13:50:33 +09:00
KOBAYASHI Shuji 4bdb1eb5aa Drop dependencies from mruby-complex to some gems 2019-12-15 22:51:07 +09:00
KOBAYASHI Shuji d2f2f9db51 Remove location info from Exception#inspect
Because location info (file name and line number) is kept in the backtrace,
it should not be kept in the result of `inspect` (and the exception object
itself), I think.

### Example

  ```ruby
  # example.rb
  begin
    raise "err"
  rescue => e
    p e
  end
  ```

#### Before this patch:

  ```
  $ bin/mruby example.rb
  example.rb:2: err (RuntimeError)
  ```

#### After this patch:

  ```
  $ bin/mruby example.rb
  err (RuntimeError)
  ```
2019-12-14 22:29:37 +09:00
dearblue cc52fa66e8 Remove module only methods from class
The `#prepend_features` and `#module_function` methods are not haves for
class objects.
2019-12-14 22:12:32 +09:00
dearblue 184ad732df Fix for #methods to include methods that were undef
If `#methods` traverse the super class, it includes the methods that
were does `undef` in the subclass.

Before patched:
```terminal
% bin/mruby -e 'p Module.instance_methods - Class.instance_methods'
[]
```

After patched:
```terminal
% bin/mruby -e 'p Module.instance_methods - Class.instance_methods'
[:append_features, :extend_object]
```
2019-12-14 21:30:44 +09:00
dearblue 69619aeeb1 Support bit flags for IO.open
Note that this bit flags are not compatible with the native flags
defined in `#include <fcntl.h>`.
2019-12-14 15:19:13 +09:00
dearblue 6d9ac89f92 Implement File#size and File#truncate 2019-12-14 15:10:57 +09:00
dearblue 5b30f789e5 Avoid method in method
And rename `File.concat_path` to `File._concat_path`.
2019-12-14 15:04:56 +09:00
dearblue c18a8c53e8 Remove unnessesary branches 2019-12-14 15:01:42 +09:00
dearblue ec1ef925a9 Fix mruby-io test for mingw32
Need `mkstemp()` implements.
2019-12-14 14:57:10 +09:00
Yukihiro "Matz" Matsumoto 6c5ee8f79e Merge pull request #4866 from shuujii/fix-arguments-check-to-Array-each
Fix arguments check to `Array#each`
2019-12-14 01:14:26 +09:00
KOBAYASHI Shuji e18aa4d893 Fix arguments check to Array#each
#### Before this patch:

  ```
  $ mruby -e '[].each(1){}'  #=> no error
  ```

#### After this patch:

  ```
  $ mruby -e '[].each(1){}'  #=> ArgumentError: wrong number of arguments
  ```
2019-12-13 17:30:34 +09:00
take-cheeze 6af555b394 Align RIStruct data for rational 2019-12-13 04:41:43 +09:00
KOBAYASHI Shuji 81de1f159c Add mrb_num_args_error() for "wrong number of arguments" error
To unify the style of messages.
2019-12-12 11:45:58 +09:00
Yukihiro "Matz" Matsumoto 9c4c82ed1c Merge pull request #4861 from shuujii/fix-behavior-of-Kernel-Integer-to-numbers-ending-with-_-and-spaces
Fix behavior of `Kernel#Integer` to numbers ending with `_` and spaces
2019-12-12 09:26:14 +09:00
KOBAYASHI Shuji 7192429e83 Fix behavior of Kernel#Integer to numbers ending with _ and spaces
#### Before this patch:

  ```ruby
  Integer("1_ ")  #=> 1
  ```

#### After this patch (same as Ruby):

  ```ruby
  Integer("1_ ")  #=> ArgumentError
  ```
2019-12-11 16:40:39 +09:00
Yukihiro "Matz" Matsumoto 994da0fd73 Merge pull request #4860 from shuujii/fix-behavior-of-String-to_i-Kernel-Integer-to-numbers-starting-with-_
Fix behavior of `String#to_i`/`Kernel#Integer` to numbers starting with `_`
2019-12-10 23:00:17 +09:00
KOBAYASHI Shuji bf431e77b8 Fix behavior of String#to_i/Kernel#Integer to numbers starting with _
#### Before this patch:

  ```ruby
  Integer("_1")  #=> 1
  "_1".to_i      #=> 1
  ```

#### After this patch (same as Ruby):

  ```ruby
  Integer("_1")  #=> ArgumentError
  "_1".to_i      #=> 0
  ```
2019-12-10 21:31:30 +09:00
Yukihiro "Matz" Matsumoto 543a9f84d1 Merge pull request #4858 from shuujii/fix-that-String-to_f-accepts-consecutive-_-as-a-numeric-expression
Fix that `String#to_f` accepts consecutive `_` as a numeric expression
2019-12-10 11:09:55 +09:00
dearblue 56de911b7a Add "mruby developers" into some gems; Resolve #4709
It is writing side by side with the original authors.
2019-12-09 23:49:03 +09:00
KOBAYASHI Shuji 0893ee492c Fix that String#to_f accepts consecutive _ as a numeric expression
Consecutive `_` is not allowed as a numeric expression:

  1_2__3             #=> SyntaxError
  Float("1_2__3")    #=> ArgumentError
  Integer("1_2__3")  #=> ArgumentError
  "1_2__3".to_i      #=> 12

But `String#to_f` accept it, so I fixed the issue.

Before this patch:

  "1_2__3".to_f      #=> 123

After this patch:

  "1_2__3".to_f      #=> 12
2019-12-09 21:47:59 +09:00
Yukihiro "Matz" Matsumoto 694089fafe Fix mrb_get_argv() to return array pointer every time; fix #4832 2019-12-09 20:50:41 +09:00
Yukihiro "Matz" Matsumoto fb9e92e828 Warnings for numbered parameters in nested blocks. 2019-12-09 20:50:41 +09:00
Yukihiro "Matz" Matsumoto f7a0f11c36 Parser refactoring on numbered parameters.
Now identifiers like `_1abc` are allowed.
2019-12-09 20:50:41 +09:00
Yukihiro "Matz" Matsumoto 0011652a28 Support new numbered parameter syntax _1 instead of @1. 2019-12-09 20:50:41 +09:00
Ukrainskiy Sergey 72d57ad094 Implement numbered parameters 2019-12-09 20:50:41 +09:00
Yukihiro "Matz" Matsumoto 8267993988 Merge pull request #4855 from dearblue/kwargs-uninit
Fix keyword arguments not be obtained with `mrb_get_args()`; Fix #4754
2019-12-09 17:31:53 +09:00
Yukihiro "Matz" Matsumoto ef644120e4 Merge pull request #4856 from shuujii/fix-the-error-message-of-Kernel-Float
Fix the error message of `Kernel#Float`
2019-12-08 21:31:14 +09:00
KOBAYASHI Shuji cf6ae0de6a Fix the error message of Kernel#Float
#### Before this patch:

  ```
  $ bin/mruby -e 'Float("1_a")'
  -e:1: invalid string for float(a) (ArgumentError)
  ```

#### After this patch:

  ```
  $ bin/mruby -e 'Float("1_a")'
  -e:1: invalid string for float("1_a") (ArgumentError)
  ```
2019-12-08 18:31:41 +09:00
Yukihiro "Matz" Matsumoto 2456d3abc0 Merge pull request #4854 from shuujii/add-tests-to-Math
Add tests to `Math`
2019-12-08 11:24:29 +09:00
dearblue 1ca4fdc4c7 Fix keyword arguments not be obtained with mrb_get_args(); Fix #4754
If ":" is after "|" and there is no "?" or "*", the keyword argument
could not be obtained and it was not initialized with `undef`.

For example: "|oo:"
2019-12-07 22:48:58 +09:00
KOBAYASHI Shuji d908a73b04 Add tests to Math 2019-12-07 20:50:56 +09:00
Yukihiro "Matz" Matsumoto 6e5c861fff Merge pull request #4852 from shuujii/auto-detect-MRB_TIME_T_UINT
Auto detect `MRB_TIME_T_UINT`
2019-12-06 08:00:53 +09:00
KOBAYASHI Shuji e6033e00fe Auto detect MRB_TIME_T_UINT 2019-12-05 21:40:15 +09:00
Yukihiro "Matz" Matsumoto 52318b3359 Merge pull request #4851 from shuujii/refine-mrb_alloca
Refine `mrb_alloca()`
2019-12-05 09:40:44 +09:00
KOBAYASHI Shuji a030446a94 Refine mrb_alloca()
* The allocated memory is guaranteed to be aligned for any data type (it was
  not guaranteed when string type is embed).
* Make allocation size exactly specified size (does not allocate space for a
  null byte).
2019-12-04 22:21:00 +09:00
Yukihiro "Matz" Matsumoto bc22991ac3 Merge pull request #4850 from shuujii/silence-Clang-warning-with-MRB_INT64-and-MRB_32BIT-in-time.c
Silence Clang warning with `MRB_INT64` and `MRB_32BIT` in `time.c`
2019-12-04 07:10:17 +09:00
KOBAYASHI Shuji ea1911d23f Silence Clang warning with MRB_INT64 and MRB_32BIT in time.c
Silence the following warnings:

  ```
  /mruby/mrbgems/mruby-time/src/time.c:871:15: warning: result of comparison of constant 9223372036854775807 with expression of type 'time_t' (aka 'long') is always false [-Wtautological-constant-out-of-range-compare]
    if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) {
        ~~~~~~~ ^ ~~~~~~~~~~~
  /mruby/mrbgems/mruby-time/src/time.c:871:40: warning: result of comparison of constant -9223372036854775808 with expression of type 'time_t' (aka 'long') is always false [-Wtautological-constant-out-of-range-compare]
    if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) {
                                 ~~~~~~~ ^ ~~~~~~~~~~~
  /mruby/mrbgems/mruby-time/src/time.c:887:16: warning: result of comparison of constant 9223372036854775807 with expression of type 'time_t' (aka 'long') is always false [-Wtautological-constant-out-of-range-compare]
    if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) {
        ~~~~~~~~ ^ ~~~~~~~~~~~
  /mruby/mrbgems/mruby-time/src/time.c:887:42: warning: result of comparison of constant -9223372036854775808 with expression of type 'time_t' (aka 'long') is always false [-Wtautological-constant-out-of-range-compare]
    if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) {
                                ~~~~~~~~ ^ ~~~~~~~~~~~
  ```
2019-12-03 22:50:50 +09:00
Yukihiro "Matz" Matsumoto 54f2ed6afd Merge pull request #4849 from shuujii/silence-Clang-warning-with-MRB_INT32-and-MRB_64BIT-in-time.c
Silence Clang warning with `MRB_INT32` and `MRB_64BIT` in `time.c`
2019-12-03 22:35:44 +09:00
KOBAYASHI Shuji 6973539005 Silence Clang warning with MRB_INT32 and MRB_64BIT in time.c
Silence the following warning:

  ```
  /mruby/mrbgems/mruby-time/src/time.c:258:60: warning: result of comparison of constant -9223372036854775808 with expression of type 'mrb_int' (aka 'int') is always false [-Wtautological-constant-out-of-range-compare]
        if ((mrb_time_int)i > MRB_TIME_MAX || MRB_TIME_MIN > i) {
                                              ~~~~~~~~~~~~ ^ ~
  ```
2019-12-02 20:00:36 +09:00
Yukihiro "Matz" Matsumoto 3c67872805 Merge pull request #4848 from shuujii/fix-MRB_FIXNUM_SHIFT-with-MRB_WORD_BOXING-MRB_INT32-and-MRB_64BIT
Fix `MRB_FIXNUM_SHIFT` with `MRB_WORD_BOXING`, `MRB_INT32` and `MRB_64BIT`
2019-12-02 13:42:16 +09:00
KOBAYASHI Shuji a53f28275e Fix MRB_FIXNUM_SHIFT with MRB_WORD_BOXING, MRB_INT32 and MRB_64BIT
### Example

  ```ruby
  # example.rb
  max32 = 2**30 - 1 + 2**30
  min32 = -max32-1
  [max32, max32+1, min32, min32-1].each{|n| p [n, n.class]}
  ```

#### Before this patch:

  ```
  $ bin/mruby example.rb
  [2147483647, Float]
  [2147483648, Float]
  [-2147483648, Float]
  [-2147483649, Float]
  ```

#### After this patch:

  ```
  $ bin/mruby example.rb
  [2147483647, Fixnum]
  [2147483648, Float]
  [-2147483648, Fixnum]
  [-2147483649, Float]
  ```
2019-12-01 22:09:38 +09:00
Yukihiro "Matz" Matsumoto ef95a9fa93 Use a string as a common regexp representation; ref #4847 2019-11-30 21:10:36 +09:00
Yukihiro "Matz" Matsumoto 25b5b79cc3 Merge pull request #4847 from shuujii/quit-mruby-v-immediately-if-no-program-is-given
Quit `mruby -v` immediately if no program is given for Ruby compatibility
2019-11-30 21:08:54 +09:00
KOBAYASHI Shuji 49653b81ea Quit mruby -v immediately if no program is given for Ruby compatibility 2019-11-30 19:52:22 +09:00
Yukihiro "Matz" Matsumoto 5eb08a0d1a Merge pull request #4846 from shuujii/fix-mruby---verbose-regression-by--4827
Fix `mruby --verbose` (regression by #4827)
2019-11-29 21:53:12 +09:00
KOBAYASHI Shuji df437eebcc Fix mruby --verbose (regression by #4827)
#### Before this patch:

  ```
  $ bin/mruby --verbose -e 'p 1'
  bin/mruby: Cannot open program file: --verbose
  ```

#### After this patch:

  ```
  $ bin/mruby --verbose -e 'p 1'
  00001 NODE_SCOPE:
  (snip)
  irep 0x7fe97041df30 nregs=4 nlocals=1 pools=0 syms=1 reps=0 iseq=11
  file: -e
      1 000 OP_LOADSELF R1
  (snip)

  1
  ```
2019-11-29 19:02:04 +09:00
Yukihiro "Matz" Matsumoto 75e96c6927 Merge pull request #4845 from shuujii/change-URL-of-mruby.org
Change the URL of `mruby.org` [ci skip]
2019-11-29 09:22:26 +09:00
KOBAYASHI Shuji 1680f2c95e Change the URL of mruby.org [ci skip]
- `http` -> `https`
- Remove `www.`
2019-11-28 17:54:52 +09:00
Yukihiro "Matz" Matsumoto 17ec885270 Merge pull request #4843 from shuujii/support-end-of-options-to-mruby-command
Support `--` (end of options) to `mruby` command
2019-11-27 22:41:36 +09:00
KOBAYASHI Shuji f4b528e07a Support -- (end of options) to mruby command
#### Before this patch:

  ```
  $ bin/mruby -e 'p ARGV' -- -x
  bin/mruby: invalid option -- (-h will show valid options)
  ```

#### After this patch:

  ```
  $ bin/mruby -e 'p ARGV' -- -x
  ["-x"]
  ```
2019-11-27 19:51:43 +09:00
Yukihiro "Matz" Matsumoto 190649e591 Merge pull request #4837 from shuujii/add-assertion-to-RVALUE-size
Add assertion to `RVALUE` size
2019-11-27 09:47:35 +09:00
Yukihiro "Matz" Matsumoto ec957ec5ee Merge pull request #4838 from shuujii/rename-BITSIZE-to-BIT-and-BIT-to-BIT_POS-for-consistency
Rename `BITSIZE` to `BIT` and `BIT` to `BIT_POS` for consistency
2019-11-26 06:31:48 +09:00
Yukihiro "Matz" Matsumoto ff15a586a0 Merge pull request #4841 from shuujii/fix-ARGV-value-in-mruby-command-regression-by-4827
Fix `ARGV` value in `mruby` command (regression by #4827)
2019-11-25 23:19:17 +09:00
KOBAYASHI Shuji f9bd414350 Fix ARGV value in mruby command (regression by #4827)
#### Before this patch:

  ```
  $ bin/mruby -e 'p ARGV' a b
  ["bin/mruby", "-e", "p ARGV", "a", "b"]
  ```

#### After this patch:

  ```
  $ bin/mruby -e 'p ARGV' a b
  ["a", "b"]
  ```
2019-11-25 21:56:27 +09:00
Yukihiro "Matz" Matsumoto a89d15cdde Merge pull request #4827 from shuujii/support-short-options-concatenation-to-mruby-command
Support short options concatenation to `mruby` command
2019-11-25 09:49:28 +09:00
Yukihiro "Matz" Matsumoto 1d1c81258e Merge pull request #4840 from shuujii/remove-unused-methods-of-MRubyIOTestUtil
Remove unused methods of `MRubyIOTestUtil`
2019-11-24 23:07:15 +09:00
KOBAYASHI Shuji ce553fa834 Remove unused methods of MRubyIOTestUtil 2019-11-24 21:40:22 +09:00
Yukihiro "Matz" Matsumoto b3e6a993a9 Merge pull request #4834 from shuujii/use-proper-PEEK-macro-for-OP_EPUSH-in-patch_irep
Use proper `PEEK` macro for `OP_EPUSH` in `patch_irep`; fix #4833
2019-11-24 07:52:17 +09:00
KOBAYASHI Shuji 375c1ebc41 Rename BITSIZE to BIT and BIT to BIT_POS for consistency
The bit width terminology is unified to `BIT` according to `MRB_INT_BIT`
and `CHAR_BIT`. Also the bit position terminology is unified to `BIT_POS`.
2019-11-23 20:40:23 +09:00
KOBAYASHI Shuji 6cf99d12ac Add assertion to RVALUE size 2019-11-23 17:36:46 +09:00
Yukihiro "Matz" Matsumoto 56f9106d94 Merge pull request #4836 from shuujii/allow-true-false-argument-to-Kernel-exit
Allow `true`/`false` argument to `Kernel#exit`
2019-11-23 06:25:02 +09:00
Yukihiro "Matz" Matsumoto 8bcf44669c Merge pull request #4835 from shuujii/introduce-mrb_ssize-type-for-buffer-size-on-memory
Introduce `mrb_ssize` type for buffer size on memory; ref #4483
2019-11-22 19:40:19 +09:00
KOBAYASHI Shuji d81e4d71c1 Allow true/false argument to Kernel#exit 2019-11-22 18:29:38 +09:00
KOBAYASHI Shuji a2df247063 Introduce mrb_ssize type for buffer size on memory; ref #4483
Previously, `mrb_int` was used as the type that represents the buffer size
on memory, but the sizes of `RString` and `RArray` exceed 6 words when
`MRB_INT64` is enabled on 32-bit CPU.

I don't think it is necessary to be able to represent the buffer size on
memory that exceeds the virtual address space. Therefore, for this purpose,
introduce `mrb_ssize` which doesn't exceed the sizes of `mrb_int` and
pointer.

I think all `mrb_int` used for this purpose should be changed to
`mrb_ssize`, but currently only the members of the structures (`RString`,
`mrb_shared_string`, `RArray` and `mrb_shared_array`) are changed.
2019-11-21 19:34:02 +09:00
KOBAYASHI Shuji 8596edba09 Use proper PEEK macro for OP_EPUSH in patch_irep; fix #4833 2019-11-20 16:00:58 +09:00
Yukihiro "Matz" Matsumoto 1bb1df19d8 Merge pull request #4831 from shuujii/always-enable-the-rational-and-complex-literals
Always enable the rational and complex literals
2019-11-19 23:32:16 +09:00
Yukihiro "Matz" Matsumoto 125c660974 Merge pull request #4830 from mruby/stable
Release `mruby 2.1.0`.
2019-11-19 23:30:37 +09:00
KOBAYASHI Shuji 351c9c80e7 Always enable the rational and complex literals
I think they can always be enabled because the regular expression literal is
always enabled.
2019-11-19 21:10:59 +09:00
Hiroshi Mimaki 57a56ddaa2 Release mruby 2.1.0. 2019-11-19 18:58:11 +09:00
Yukihiro "Matz" Matsumoto 79e73dd86a Merge pull request #4828 from shuujii/refactor-mrb_string_value_cstr
Refactor `mrb_string_value_cstr`
2019-11-19 02:52:39 +09:00
KOBAYASHI Shuji 3241a7e5a8 Refactor mrb_string_value_cstr
- Keep `MRB_STR_ASCII` flag.
- Avoid a string object creation.
2019-11-19 01:07:58 +09:00
Yukihiro "Matz" Matsumoto bd87799673 Merge pull request #4825 from shuujii/fix-argument-specs-to-Kernel
Fix argument specs to `Kernel`
2019-11-18 08:15:58 +09:00
KOBAYASHI Shuji 9de7130a9a Support short options concatenation to mruby command
#### Before this patch:

  ```
  $ bin/mruby -ce 1
  bin/mruby: Cannot open program file: 1
  ```

#### After this patch:

  ```
  $ bin/mruby -ce 1
  Syntax OK
  ```
2019-11-17 16:38:50 +09:00
Yukihiro "Matz" Matsumoto 74310f41d7 Merge pull request #4826 from shuujii/revert-Implement-Ruby2.7-frozen-strings-from-Symbol-to_s
Revert "Implement Ruby2.7's frozen strings from `Symbol#to_s`"
2019-11-17 04:38:46 +09:00
KOBAYASHI Shuji a367373fe3 Revert "Implement Ruby2.7's frozen strings from Symbol#to_s"
This feature was reverted from Ruby 2.7.
2019-11-16 19:47:31 +09:00
KOBAYASHI Shuji 04baaab311 Fix argument specs to Kernel 2019-11-15 19:07:42 +09:00
Yukihiro "Matz" Matsumoto c9f156ef0c Merge pull request #4823 from shuujii/fix-here-document-with-EOF
Fix here document with EOF
2019-11-15 08:16:33 +09:00
KOBAYASHI Shuji 455930fbc4 Fix here document with EOF
#### Before this patch:

  ```
  $ bin/mruby -e 'p <<EOS
1
EOS'
  -e:4:0: can't find heredoc delimiter "EOS" anywhere before EOF
  -e:4:0: syntax error, unexpected $end, expecting tHEREDOC_END or tHD_STRING_PART or tHD_STRING_MID
  ```

#### After this patch (same as Ruby):

  ```
  $ bin/mruby -e 'p <<EOS
1
EOS'
  "1\n"
  ```
2019-11-14 20:28:36 +09:00
Yukihiro "Matz" Matsumoto db43738397 Merge pull request #4821 from shuujii/use-mrb_intern_lit-if-possible-in-parse.y
Use `mrb_intern_lit` if possible in `parse.y`
2019-11-13 21:08:47 +09:00
Yukihiro "Matz" Matsumoto 079aff1779 Revert a76dc04 to resolve #4820 2019-11-13 21:06:26 +09:00
KOBAYASHI Shuji 29133b2fe2 Use mrb_intern_lit if possible in parse.y 2019-11-13 19:20:47 +09:00
Yukihiro "Matz" Matsumoto 37c8cbe76b Merge pull request #4819 from shuujii/use-intern-instead-of-intern_cstr-if-possible-in-parse.y
Use `intern` instead of `intern_cstr` if possible in `parse.y`
2019-11-13 08:10:50 +09:00
KOBAYASHI Shuji ac917983c5 Use intern instead of intern_cstr if possible in parse.y 2019-11-12 21:04:12 +09:00
Yukihiro "Matz" Matsumoto 1259564c01 Merge pull request #4818 from shuujii/fix-argument-specs-to-Integer
Fix argument specs to `Integer`
2019-11-12 08:33:21 +09:00
KOBAYASHI Shuji edbc6d8ab5 Fix argument specs to Integer 2019-11-11 20:48:52 +09:00
Yukihiro "Matz" Matsumoto c268e36e44 Require Regexp.escape before interpolating build_dir; fix #4817 2019-11-11 18:13:24 +09:00
Yukihiro "Matz" Matsumoto 067c11f65d Merge pull request #4816 from shuujii/defer-getting-caller_dir-until-needed-in-MRubyLoadGems-gem
Defer getting `caller_dir` until needed in `MRuby::LoadGems#gem`
2019-11-11 07:33:31 +09:00
KOBAYASHI Shuji b5946822af Defer getting caller_dir until needed in MRuby::LoadGems#gem 2019-11-10 19:40:07 +09:00
Yukihiro "Matz" Matsumoto cc54257de5 Merge pull request #4814 from shuujii/fix-argument-specs-to-IO
Fix argument specs to `IO`
2019-11-10 08:29:55 +09:00
KOBAYASHI Shuji a72917541f Fix argument specs to IO 2019-11-09 22:08:00 +09:00
Yukihiro "Matz" Matsumoto e50344b5da Avoid unnecessary Symbol#to_s call; fix #4812 2019-11-08 23:38:40 +09:00
Yukihiro "Matz" Matsumoto 1a0c799898 Merge pull request #4813 from shuujii/remove-unneeded-dependency-from-mruby-hash-ext
Remove unneeded dependency from `mruby-hash-ext`
2019-11-08 23:37:40 +09:00
KOBAYASHI Shuji ac213907d7 Remove unneeded dependency from mruby-hash-ext 2019-11-08 20:40:20 +09:00
Yukihiro "Matz" Matsumoto 7750c61e29 Fixed a bug in keyword arguments in block parameters; fix #4810
This is caused by incomplete fix in #4746
2019-11-08 14:06:46 +09:00
Yukihiro "Matz" Matsumoto 8ff001ef30 Avoid crashing of Array#unshift; fix #4808
On cases like `a.unshift(*a)`.
2019-11-08 10:57:18 +09:00
Yukihiro "Matz" Matsumoto 962776fe25 Allow here-doc before closing parentheses; ref #4796 2019-11-08 09:50:48 +09:00
Yukihiro "Matz" Matsumoto 0f64cb421e Merge pull request #4811 from shuujii/clear-MRB_STR_SHARED-flag-in-mrb_str_modify_keep_ascii
Clear `MRB_STR_SHARED` flag in `mrb_str_modify_keep_ascii`; close #4807
2019-11-08 08:12:23 +09:00
KOBAYASHI Shuji 45aa5081e4 Clear MRB_STR_SHARED flag in mrb_str_modify_keep_ascii; close #4807 2019-11-07 22:16:59 +09:00
Yukihiro "Matz" Matsumoto c10e191ac7 Merge pull request #4806 from shuujii/drop-test-dependency-from-mruby-hash-ext-to-mruby-enumerator
Drop test dependency from `mruby-hash-ext` to `mruby-enumerator`
2019-11-06 21:10:21 +09:00
KOBAYASHI Shuji ea2424d36d Drop test dependency from mruby-hash-ext to mruby-enumerator 2019-11-06 18:57:35 +09:00
Yukihiro "Matz" Matsumoto 1cc0180a81 Merge pull request #4805 from shuujii/remove-test-that-depend-on-mruby-enumerator-from-mruby-array-ext
Remove test that depend on `mruby-enumerator` from `mruby-array-ext`
2019-11-05 21:35:06 +09:00
KOBAYASHI Shuji b5bb981959 Remove test that depend on mruby-enumerator from mruby-array-ext
`Object.const_defined?(:Enumerator)` is always false because
`mruby-enumerator` is not specified in `test_dependency`. I don't
think this test is necessary.
2019-11-05 19:45:04 +09:00
Yukihiro "Matz" Matsumoto ee86721ef9 Merge pull request #4804 from shuujii/avoid-using-C++-style-comments-in-parse.y
Avoid using C++ style comments (`//`) in `parse.y` [ci skip]
2019-11-05 17:08:53 +09:00
KOBAYASHI Shuji 4841754aba Avoid using C++ style comments (//) in parse.y [ci skip] 2019-11-04 22:12:59 +09:00
Yukihiro "Matz" Matsumoto 2166cc2e80 Merge pull request #4803 from shuujii/remove-unused-enum-in-mrb_cstr_to_dbl
Remove unused enum in `mrb_cstr_to_dbl`
2019-11-03 22:31:35 +09:00
KOBAYASHI Shuji bf0b591b2f Remove unused enum in mrb_cstr_to_dbl 2019-11-03 19:39:25 +09:00
Yukihiro "Matz" Matsumoto 5812d05b71 Merge pull request #4802 from shuujii/fix-argument-specs-to-Hash
Fix argument specs to `Hash`
2019-11-02 19:40:48 +09:00
KOBAYASHI Shuji 7a06e49008 Fix argument specs to Hash 2019-11-02 17:37:43 +09:00
Yukihiro "Matz" Matsumoto 8cbee9695b Merge pull request #4801 from shuujii/fix-argument-specs-to-File
Fix argument specs to `File`
2019-11-02 08:40:22 +09:00
KOBAYASHI Shuji 7e03f47370 Fix argument specs to File 2019-11-01 22:02:18 +09:00
KOBAYASHI Shuji ad6c58972c Set MRB_STR_ASCII flag to some stringize methods
- `Fixnum#to_s`, `Fixnum#inspect`
- `Float#to_s`, `Float#inspect`
- `NilClass#to_s`, `NilClass#inspect`
- `FalseClass#to_s`, `FalseClass#inspect`
- `TrueClass#to_s`, `TrueClass#inspect`
- `Time#to_s`, `Time#inspect`
2019-10-31 22:04:56 +09:00
Yukihiro "Matz" Matsumoto ad7f9b3542 Merge pull request #4799 from shuujii/fix-argument-specs-to-Fiber
Fix argument specs to `Fiber`
2019-10-31 11:29:19 +09:00
KOBAYASHI Shuji e4d078b520 Fix argument specs to Fiber 2019-10-30 23:00:22 +09:00
Yukihiro "Matz" Matsumoto 1dc0da8218 Fix here-doc inside parens and brackets; fix #4796 2019-10-30 10:05:28 +09:00
mimaki a9e27933a9 Fix file/directory name parameter for git command. 2019-10-30 09:32:24 +09:00
Yukihiro "Matz" Matsumoto fdc0219db5 Merge pull request #4798 from mimaki/fix-git-params-for-windows
Fix `git` command parameter for Windows.
2019-10-30 00:40:58 +09:00
Yukihiro "Matz" Matsumoto ecdc6c6507 Merge pull request #4797 from shuujii/remove-unneeded-Array-creation-in-Struct-_inspect
Remove unneeded `Array` creation in `Struct#_inspect`
2019-10-30 00:39:44 +09:00
mimaki f68212cc7a Fix file/directory name parameter for git command. 2019-10-29 20:56:12 +09:00
KOBAYASHI Shuji e23840a3fc Remove unneeded Array creation in Struct#_inspect 2019-10-29 20:55:28 +09:00
Yukihiro "Matz" Matsumoto 34f68d0104 Merge pull request #4795 from shuujii/remove-documents-about-Regexp-argument-from-string
Remove documents about `Regexp` argument from `String#{[],[]=}` [ci skip]
2019-10-28 22:24:04 +09:00
KOBAYASHI Shuji 23cb78a0ff Remove documents about Regexp argument from String#{[],[]=} [ci skip] 2019-10-28 18:37:40 +09:00
Yukihiro "Matz" Matsumoto 552bd9daff Merge pull request #4792 from shuujii/refine-String-split-document
Refine `String#split` document
2019-10-27 22:52:50 +09:00
KOBAYASHI Shuji 799ad0e1c7 Refine String#split document 2019-10-27 19:14:12 +09:00
Yukihiro "Matz" Matsumoto 8710a22c31 Merge pull request #4791 from shuujii/optimize-chars2bytes-with-MRB_UTF8_STRING-to-ASCII-only-string
Optimize `chars2bytes` with `MRB_UTF8_STRING` to ASCII only string
2019-10-26 23:09:30 +09:00
KOBAYASHI Shuji db0a4d9045 Optimize chars2bytes with MRB_UTF8_STRING to ASCII only string
### Benchmark (with `MRB_UTF8_STRING`)

  ```
  $ mruby -e '
    COUNT = 150000
    SIZE = 10000
    strs = Array.new(COUNT) do
      s = "a" * SIZE
      s.size  # set `MRB_STR_ASCII` flag
      s
    end
    i = 0
    t = Time.now
    while i < COUNT
      strs[i][-2..-1] = ""
      i += 1
    end
    printf "%.2f sec\n", Time.now - t
  '

  1.10 sec  # before
  0.07 sec  # after
  ```
2019-10-26 22:19:04 +09:00
Yukihiro "Matz" Matsumoto 9c99451607 Merge pull request #4790 from shuujii/squeeze-redundant-spaces
Squeeze redundant spaces in `test/t/numeric.rb` [ci skip]
2019-10-25 22:14:18 +09:00
KOBAYASHI Shuji 4b14c4633a Squeeze redundant spaces in test/t/numeric.rb [ci skip] 2019-10-25 19:39:31 +09:00
Yukihiro "Matz" Matsumoto 39a0a25f20 Merge pull request #4788 from shuujii/fix-argument-specs-to-Exception
Fix argument specs to `Exception`
2019-10-25 08:21:53 +09:00
KOBAYASHI Shuji 85e34f1ca4 Fix argument specs to Exception 2019-10-24 22:24:40 +09:00
Yukihiro "Matz" Matsumoto b4262972dc Merge pull request #4787 from shuujii/optimize-str_subseq-with-MRB_UTF8_STRING-to-ASCII-only-string
Optimize `str_subseq` with `MRB_UTF8_STRING` to ASCII only string
2019-10-23 20:12:55 +09:00
KOBAYASHI Shuji 06bd4ffdaf Optimize str_subseq with MRB_UTF8_STRING to ASCII only string
### Benchmark (with `MRB_UTF8_STRING`)

  ```ruby
  # benchmark.rb
  COUNT = 300000
  SIZE = 10000
  s = "a" * SIZE
  s.size  # set `MRB_STR_ASCII` flag
  i = 0
  while i < COUNT
    s[-1]
    i += 1
  end
  ```

#### Before this patch:

  ```
  $ time mruby benchmark.rb
          2.06 real         2.05 user         0.00 sys
  ```

#### After this patch:

  ```
  $ time mruby benchmark.rb
          0.05 real         0.04 user         0.00 sys
  ```
2019-10-23 19:03:39 +09:00
Hiroshi Mimaki 4eb8fca140 Merge branch 'master' into stable 2019-10-23 15:44:21 +09:00
Yukihiro "Matz" Matsumoto fa85f91e0e Add type cast to avoid an error from int and enum mixture; fix #4786 2019-10-23 14:47:55 +09:00
Yukihiro "Matz" Matsumoto 9540a8309c Remove unnecessary mrb_funcall(). 2019-10-23 14:47:55 +09:00
Yukihiro "Matz" Matsumoto 11184e9186 Remove unnecessary mrb_string_p() check. 2019-10-23 14:47:55 +09:00
Yukihiro "Matz" Matsumoto 2f0bf1e110 Merge pull request #4785 from shuujii/fix-incorrect-MRB_STR_ASCII-flag-update-in-mrb_str_dump
Fix incorrect `MRB_STR_ASCII` flag update in `mrb_str_dump`
2019-10-23 09:55:47 +09:00
KOBAYASHI Shuji 41c43234a7 Fix incorrect MRB_STR_ASCII flag update in mrb_str_dump
### Example (with `MRB_UTF8_STRING`)

  ```ruby
  s = "\u3042"
  p s.size
  s.dump
  p s.size
  ```

#### Before this patch:

  ```
  1
  3
  ```

#### After this patch:

  ```
  1
  1
  ```
2019-10-22 21:56:40 +09:00
Yukihiro "Matz" Matsumoto 1aacde20fa Merge pull request #4784 from shuujii/remove-Kernel-getc
Remove `Kernel#getc`
2019-10-21 21:27:02 +09:00
KOBAYASHI Shuji 941b99955a Remove Kernel#getc
`Kernel#getc` has been removed since Ruby 1.9 and is not defined in ISO.
2019-10-21 18:50:52 +09:00
Yukihiro "Matz" Matsumoto 0701cc493c Merge pull request #4783 from shuujii/use-mrb_str_cat_str-instead-of-mrb_str_concat-if-possible
Use `mrb_str_cat_str` instead of `mrb_str_concat` if possible
2019-10-20 20:24:10 +09:00
KOBAYASHI Shuji 7047c52d7b Use mrb_str_cat_str instead of mrb_str_concat if possible 2019-10-20 16:26:10 +09:00
Yukihiro "Matz" Matsumoto fddefeb7ee Merge pull request #4781 from shuujii/fix-that-Module-to_s-may-return-frozen-string
Fix that `Module#to_s` may return frozen string; ref 08eafe2
2019-10-19 17:55:26 +09:00
KOBAYASHI Shuji 347729a7c0 Fix that Module#to_s may return frozen string; ref 08eafe2 2019-10-19 17:27:17 +09:00
Yukihiro "Matz" Matsumoto 7957f75bd8 Merge pull request #4779 from take-cheeze/print_mrbc_cmd
Print mrbc command on verbose mode
2019-10-19 11:12:03 +09:00
take-cheeze 4877dbf2a9 Print mrbc command on verbose mode 2019-10-19 01:42:34 +09:00
178 changed files with 18846 additions and 4273 deletions
+106
View File
@@ -0,0 +1,106 @@
name: Build & Test
on: [push, pull_request]
jobs:
Ubuntu-1604:
runs-on: ubuntu-16.04
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt install ruby gperf
- name: build and test
run: rake -m -j4 all test
env:
MRUBY_CONFIG: travis_config.rb
Ubuntu-1804-gcc:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt install ruby gperf gcc g++
- name: build and test
run: rake -m -j4 all test
env:
MRUBY_CONFIG: travis_config.rb
CC: gcc
CXX: g++
Ubuntu-1804-clang:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
- name: apt
run: sudo apt install ruby gperf
- name: build and test
run: rake -m -j4 all test
env:
MRUBY_CONFIG: travis_config.rb
CC: clang
CXX: clang++
macOS:
runs-on: macos-latest
steps:
- uses: actions/checkout@v1
- name: brew
run: brew install ruby gperf
- name: build and test
run: rake -m -j4 all test
env:
MRUBY_CONFIG: travis_config.rb
Windows-MinGW:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- name: chocolatey
run: choco install -y ruby gperf
- name: build and test
run: rake -E '$stdout.sync=true' -j4 test
env:
MRUBY_CONFIG: travis_config.rb
CFLAGS: -g -O1 -Wall -Wundef
Windows-Cygwin:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- uses: actions/cache@v1
with:
path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
key: ${{ runner.os }}-cygwin-chocolatey-${{ matrix.os }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-cygwin-chocolatey-${{ matrix.os }}-
${{ runner.os }}-cygwin-chocolatey-
- name: chocolatey
run: choco install -y cygwin
- name: Install cygwin packages
shell: cmd
run: C:\tools\cygwin\cygwinsetup.exe -qgnNdO -R C:/tools/cygwin -l C:/tools/cygwin/package -s http://mirrors.kernel.org/sourceware/cygwin/ -P gcc-core,gcc-g++,make,gperf,ruby
- name: Set ENV
run: |
echo '::set-env name=PATH::C:\tools\cygwin\bin;C:\tools\cygwin\usr\bin'
- name: build and test
shell: cmd
run: C:\tools\cygwin\bin\ruby.exe /usr/bin/rake -m -j4 -E 'STDOUT.sync=true' test
env:
MRUBY_CONFIG: travis_config.rb
Windows-VC:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
- name: chocolatey
run: choco install -y ruby gperf
- name: build and test
shell: cmd
run: |
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
rake -E "STDOUT.sync=true" -m -j4 test
env:
MRUBY_CONFIG: appveyor_config.rb
# TODO(take-cheeze): Re-enable /O2
CFLAGS: "/c /nologo /W3 /we4013 /Zi /MD /D_CRT_SECURE_NO_WARNINGS"
CXXFLAGS: "/c /nologo /W3 /Zi /MD /EHs /D_CRT_SECURE_NO_WARNINGS"
+51
View File
@@ -0,0 +1,51 @@
name: "Code scanning - action"
on:
push:
pull_request:
schedule:
- cron: '0 19 * * 4'
jobs:
CodeQL-Build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2
# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
+24
View File
@@ -0,0 +1,24 @@
name: CIFuzz
on: [pull_request]
jobs:
Fuzzing:
runs-on: ubuntu-latest
steps:
- name: Build Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
with:
oss-fuzz-project-name: 'mruby'
dry-run: false
- name: Run Fuzzers
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
with:
oss-fuzz-project-name: 'mruby'
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v1
if: failure()
with:
name: artifacts
path: ./out/artifacts
+3
View File
@@ -17,6 +17,9 @@
.svn
.vscode
.yardoc
.ccls*
compile_flags.txt
compile_commands.json
cscope.files
cscope.out
tags
+1601 -401
View File
File diff suppressed because it is too large Load Diff
+6 -14
View File
@@ -1,19 +1,11 @@
language: c
sudo: false
matrix:
include:
- os: linux
sudo: false
- os: osx
osx_image: xcode7.1
addons:
apt:
packages:
- gperf
jobs:
- os: linux
- os: osx
env:
- MRUBY_CONFIG=travis_config.rb
script: "./minirake -j4 all test"
script:
- rake -m && rake test
+1
View File
@@ -42,3 +42,4 @@ of this list.
Masahiro Wakame
YAMAMOTO Masaya
KOBAYASHI Shuji
RIZAL Reckordp
+1 -1
View File
@@ -9,7 +9,7 @@ things in mind before submitting your pull request:
* Work on the latest possible state of **mruby/master**
* Create a branch which is dedicated to your change
* Test your changes before creating a pull request (```./minirake test```)
* Test your changes before creating a pull request (```rake test```)
* If possible write a test case which confirms your change
* Don't mix several features or bug-fixes in one pull request
* Create a meaningful commit message
+1 -1
View File
@@ -6,7 +6,7 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "mruby"
PROJECT_NUMBER = 2.1.0
PROJECT_NUMBER = 2.1.2
PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language"
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2019 mruby developers
Copyright (c) 2020 mruby developers
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
+1 -3
View File
@@ -1,8 +1,6 @@
# mruby is using Rake (http://rake.rubyforge.org) as a build tool.
# We provide a minimalistic version called minirake inside of our
# codebase.
RAKE = ruby ./minirake
RAKE = rake
all :
$(RAKE)
+7 -7
View File
@@ -17,7 +17,7 @@ of the Ministry of Economy, Trade and Industry of Japan.
## How to get mruby
The stable version 2.1.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.1.0.zip](https://github.com/mruby/mruby/archive/2.1.0.zip)
The stable version 2.1.2 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.1.2.zip](https://github.com/mruby/mruby/archive/2.1.2.zip)
The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master)
@@ -30,11 +30,11 @@ You can also install and compile mruby using [ruby-install](https://github.com/p
## mruby home-page
The URL of the mruby home-page is: [http://www.mruby.org](http://www.mruby.org).
The URL of the mruby home-page is: https://mruby.org.
## Mailing list
We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby).
We don't have a mailing list, but you can use [GitHub issues](https://github.com/mruby/mruby/issues).
## How to compile and install (mruby and gems)
@@ -44,11 +44,11 @@ See the [compile.md](https://github.com/mruby/mruby/blob/master/doc/guides/compi
To run the tests, execute the following from the project's root directory.
$ make test
$ rake test
Or
$ ruby ./minirake test
Note: `bison` bundled with MacOS is too old to compile `mruby`.
Try `brew install bison` and follow the instuction shown to update
the `$PATH` to compile `mruby`.
## Building documentation
+9 -8
View File
@@ -5,6 +5,8 @@ MRUBY_ROOT = File.dirname(File.expand_path(__FILE__))
MRUBY_BUILD_HOST_IS_CYGWIN = RUBY_PLATFORM.include?('cygwin')
MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd')
Rake.verbose(false) if Rake.verbose == Rake::DSL::DEFAULT
$LOAD_PATH << File.join(MRUBY_ROOT, "lib")
# load build systems
@@ -33,10 +35,9 @@ load "#{MRUBY_ROOT}/tasks/gitlab.rake"
load "#{MRUBY_ROOT}/tasks/doc.rake"
def install_D(src, dst)
opts = { :verbose => $verbose }
FileUtils.rm_f dst, opts
FileUtils.mkdir_p File.dirname(dst), opts
FileUtils.cp src, dst, opts
rm_f dst
mkdir_p File.dirname(dst)
cp src, dst
end
##############################
@@ -62,7 +63,7 @@ MRuby.each_target do |target|
relative_from_root = gem.dir.relative_path_from(MRUBY_ROOT)
current_build_dir = File.expand_path "#{build_dir}/#{relative_from_root}"
if current_build_dir !~ /^#{build_dir}/
if current_build_dir !~ /^#{Regexp.escape(build_dir)}/
current_build_dir = "#{build_dir}/mrbgems/#{gem.name}"
end
@@ -144,16 +145,16 @@ end
desc "clean all built and in-repo installed artifacts"
task :clean do
MRuby.each_target do |t|
FileUtils.rm_rf t.build_dir, { :verbose => $verbose }
rm_rf t.build_dir
end
FileUtils.rm_f depfiles, { :verbose => $verbose }
rm_f depfiles
puts "Cleaned up target build folder"
end
desc "clean everything!"
task :deep_clean => ["clean", "clean_doc"] do
MRuby.each_target do |t|
FileUtils.rm_rf t.gem_clone_dir, { :verbose => $verbose }
rm_rf t.gem_clone_dir
end
puts "Cleaned up mrbgems build folder"
end
+9 -12
View File
@@ -4,20 +4,23 @@ os: Visual Studio 2017
shallow_clone: true
cache:
- win_flex_bison
environment:
matrix:
# Visual Studio 2017 64bit
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat
# Visual Studio 2017 32bit
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat
machine: x86
# Visual Studio 2015 64bit
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
machine: amd64
# Visual Studio 2015 32bit
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
machine: x86
# Visual Studio 2013 64bit
- visualcpp: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
machine: amd64
@@ -30,13 +33,7 @@ init:
- ruby --version
install:
- if not exist win_flex_bison (
appveyor DownloadFile "https://github.com/lexxmark/winflexbison/releases/download/v.2.5.10/win_flex_bison-2.5.10.zip" &
7z x -y -owin_flex_bison win_flex_bison-2.5.10.zip
)
build_script:
- set YACC=.\win_flex_bison\win_bison.exe
- set MRUBY_CONFIG=appveyor_config.rb
- rake -m
- rake -E $stdout.sync=true test
+8 -12
View File
@@ -1,14 +1,7 @@
MRuby::Build.new('debug') do |conf|
toolchain :visualcpp
enable_debug
# include all core GEMs
conf.gembox 'full-core'
conf.compilers.each do |c|
c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA MRB_METHOD_CACHE)
end
build_mrbc_exec
def setup_option(conf)
conf.cc.flags[0].delete("/Zi") unless ENV['CFLAGS']
conf.cxx.flags[0].delete("/Zi") unless ENV['CFLAGS'] || ENV['CXXFLAGS']
conf.linker.flags << "/DEBUG:NONE" unless ENV['LDFLAGS']
end
MRuby::Build.new('full-debug') do |conf|
@@ -17,7 +10,8 @@ MRuby::Build.new('full-debug') do |conf|
# include all core GEMs
conf.gembox 'full-core'
conf.cc.defines += %w(MRB_ENABLE_DEBUG_HOOK)
conf.cc.defines += %w(MRB_GC_STRESS MRB_METHOD_CACHE MRB_ENABLE_DEBUG_HOOK)
setup_option(conf)
conf.enable_test
end
@@ -30,6 +24,7 @@ MRuby::Build.new do |conf|
conf.compilers.each do |c|
c.defines += %w(MRB_GC_FIXED_ARENA)
end
setup_option(conf)
conf.enable_bintest
conf.enable_test
end
@@ -41,6 +36,7 @@ MRuby::Build.new('cxx_abi') do |conf|
conf.compilers.each do |c|
c.defines += %w(MRB_GC_FIXED_ARENA)
end
setup_option(conf)
conf.enable_bintest
conf.enable_test
+6 -6
View File
@@ -30,9 +30,9 @@ MRuby::Build.new do |conf|
# cc.flags = [ENV['CFLAGS'] || %w()]
# cc.include_paths = ["#{root}/include"]
# cc.defines = %w()
# cc.option_include_path = '-I%s'
# cc.option_include_path = %q[-I"%s"]
# cc.option_define = '-D%s'
# cc.compile_options = "%{flags} -MMD -o %{outfile} -c %{infile}"
# cc.compile_options = %Q[%{flags} -MMD -o "%{outfile}" -c "%{infile}"]
# end
# mrbc settings
@@ -50,25 +50,25 @@ MRuby::Build.new do |conf|
# linker.library_paths = []
# linker.option_library = '-l%s'
# linker.option_library_path = '-L%s'
# linker.link_options = "%{flags} -o %{outfile} %{objs} %{libs}"
# linker.link_options = "%{flags} -o "%{outfile}" %{objs} %{libs}"
# end
# Archiver settings
# conf.archiver do |archiver|
# archiver.command = ENV['AR'] || 'ar'
# archiver.archive_options = 'rs %{outfile} %{objs}'
# archiver.archive_options = 'rs "%{outfile}" %{objs}'
# end
# Parser generator settings
# conf.yacc do |yacc|
# yacc.command = ENV['YACC'] || 'bison'
# yacc.compile_options = '-o %{outfile} %{infile}'
# yacc.compile_options = %q[-o "%{outfile}" "%{infile}"]
# end
# gperf settings
# conf.gperf do |gperf|
# gperf.command = 'gperf'
# gperf.compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
# gperf.compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
# end
# file extensions
+10 -6
View File
@@ -6,12 +6,16 @@ binaries.
## Prerequisites
To compile mruby out of the source code you need the following tools:
* C Compiler (e.g. `gcc`)
* Linker (e.g. `gcc`)
* C Compiler (e.g. `gcc` or `clang`)
* Linker (e.g. `gcc` or `clang`)
* Archive utility (e.g. `ar`)
* Parser generator (e.g. `bison`)
* Ruby 2.0 or later (e.g. `ruby` or `jruby`)
Note that `bison` bundled with MacOS is too old to compile `mruby`.
Try `brew install bison` and follow the instuction shown to update
the `$PATH` to compile `mruby`.
Optional:
* GIT (to update mruby source and integrate mrbgems easier)
* C++ compiler (to use GEMs which include \*.cpp, \*.cxx, \*.cc)
@@ -32,10 +36,10 @@ All tools necessary to compile mruby can be set or modified here. In case
you want to maintain an additional *build_config.rb* you can define a
customized path using the *$MRUBY_CONFIG* environment variable.
To compile just call `./minirake` inside of the mruby source root. To
generate and execute the test tools call `./minirake test`. To clean
all build files call `./minirake clean`. To see full command line on
build, call `./minirake -v`.
To compile just call `rake` inside of the mruby source root. To
generate and execute the test tools call `rake test`. To clean
all build files call `rake clean`. To see full command line on
build, call `rake -v`.
## Build Configuration
+1 -1
View File
@@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option:
```bash
$ mrdb --version
mruby 2.1.0 (2019-10-18)
mruby 2.1.2 (2020-07-10)
```
## 2.2 Basic Operation
+4 -8
View File
@@ -54,17 +54,13 @@ You can use mrbconfs with following ways:
* When defined removes floating point numbers from mruby.
* It makes mruby easier to handle in "Microcontroller without FPU" and "Kernel Space".
`MRB_INT16`
* When defined `int16_t` will be defined as `mrb_int`.
* Conflicts with `MRB_INT32` and `MRB_INT64`.
`MRB_INT32`
* When defined, or both `MRB_INT16` and `MRB_INT64` are not defined on 32-bit CPU mode, `int32_t` will be defined as `mrb_int`.
* Conflicts with `MRB_INT16` and `MRB_INT64`.
* When defined, or `MRB_INT64` are not defined on 32-bit CPU mode, `mrb_int` will be defined as `int32_t`.
* Conflicts with `MRB_INT64`.
`MRB_INT64`
* When defined, or both `MRB_INT16` and `MRB_INT32` are not defined on 64-bit CPU mode, `int64_t` will be defined as `mrb_int`.
* Conflicts with `MRB_INT16` and `MRB_INT32`.
* When defined, or `MRB_INT32` are not defined on 64-bit CPU mode, `mrb_int` will be defined as `int64_t`.
* Conflicts with `MRB_INT32`.
## Garbage collector configuration.
+3 -3
View File
@@ -45,8 +45,8 @@ conf.gem mgem: 'mruby-redis', checksum_hash: '3446d19fc4a3f9697b5ddbf2a904f301c4
If there is missing dependencies, mrbgem dependencies solver will reference
mrbgem from core or mgem-list.
To pull all gems from remote GIT repository on build, call ```./minirake -p```,
or ```./minirake --pull-gems```.
To pull all gems from remote GIT repository on build, call ```rake -p```,
or ```rake --pull-gems```.
NOTE: `:bitbucket` option supports only git. Hg is unsupported in this version.
@@ -235,7 +235,7 @@ So it is recommended not to put GEM's local header files on include/.
These exports are retroactive.
For example: when B depends to C and A depends to B, A will get include paths exported by C.
Exported include_paths are automatically appended to GEM local include_paths by Minirake.
Exported include_paths are automatically appended to GEM local include_paths by rake.
You can use `spec.export_include_paths` accessor if you want more complex build.
+10 -10
View File
@@ -38,7 +38,7 @@ puts [1,2,3]
3
```
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
```
[1, 2, 3]
@@ -61,7 +61,7 @@ end
`ZeroDivisionError` is raised.
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
No exception is raised.
@@ -89,7 +89,7 @@ p Liste.new "foobar"
` [] `
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
`ArgumentError` is raised.
@@ -119,7 +119,7 @@ false
true
```
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
```
true
@@ -156,7 +156,7 @@ p 'ok'
ok
```
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
```
test.rb:8: undefined method 'test_func' (NoMethodError)
@@ -178,7 +178,7 @@ defined?(Foo)
nil
```
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
`NameError` is raised.
@@ -195,7 +195,7 @@ alias $a $__a__
` nil `
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
Syntax error
@@ -217,7 +217,7 @@ end
`ArgumentError` is raised.
The re-defined `+` operator does not accept any arguments.
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
` 'ab' `
Behavior of the operator wasn't changed.
@@ -233,7 +233,7 @@ $ ruby -e 'puts Proc.new {}.binding'
#<Binding:0x00000e9deabb9950>
```
#### mruby [2.1.0 (2019-10-18)]
#### mruby [2.1.2 (2020-07-10)]
```
$ ./bin/mruby -e 'puts Proc.new {}.binding'
@@ -255,7 +255,7 @@ $ ruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
[[{"a"=>1}], {:b=>2}]
```
#### mruby [mruby 2.1.0]
#### mruby [mruby 2.1.2]
```
$ ./bin/mruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)'
+108 -95
View File
@@ -16,7 +16,6 @@ In the table.1 below, the second field describes the size (and
sign) of operands.
* B: 8bit
* sB: signed 8bit
* S: 16bit
* sS: signed 16bit
* W: 24bit
@@ -31,97 +30,111 @@ with `"`, either `OP_EXT1` or `OP_EXT2` or `OP_EXT2` can be prefixed.
## table.1 Instruction Table
| Instruction Name | Operand type | Semantics |
|:-----------------|--------------|---------------------|
| OP_NOP | - | |
| OP_MOVE" | BB | R(a) = R(b)
| OP_LOADL" | BB | R(a) = Pool(b)
| OP_LOADI" | BsB | R(a) = mrb_int(b)
| OP_LOADI_0' | B | R(a) = 0
| OP_LOADI_1' | B | R(a) = 1
| OP_LOADI_2' | B | R(a) = 2
| OP_LOADI_3' | B | R(a) = 3
| OP_LOADSYM" | BB | R(a) = Syms(b)
| OP_LOADNIL' | B | R(a) = nil
| OP_LOADSELF' | B | R(a) = self
| OP_LOADT' | B | R(a) = true
| OP_LOADF' | B | R(a) = false
| OP_GETGV" | BB | R(a) = getglobal(Syms(b))
| OP_SETGV" | BB | setglobal(Syms(b), R(a))
| OP_GETSV" | BB | R(a) = Special[b]
| OP_SETSV" | BB | Special[b] = R(a)
| OP_GETIV" | BB | R(a) = ivget(Syms(b))
| OP_SETIV" | BB | ivset(Syms(b),R(a))
| OP_GETCV" | BB | R(a) = cvget(Syms(b))
| OP_SETCV" | BB | cvset(Syms(b),R(a))
| OP_GETCONST" | BB | R(a) = constget(Syms(b))
| OP_SETCONST" | BB | constset(Syms(b),R(a))
| OP_GETMCNST" | BB | R(a) = R(a)::Syms(b)
| OP_SETMCNST" | BB | R(a+1)::Syms(b) = R(a)
| OP_GETUPVAR' | BBB | R(a) = uvget(b,c)
| OP_SETUPVAR' | BBB | uvset(b,c,R(a))
| OP_JMP | S | pc+=a
| OP_JMPIF' | SB | if R(b) pc+=a
| OP_JMPNOT' | SB | if !R(b) pc+=a
| OP_ONERR | sS | rescue_push(pc+a)
| OP_EXCEPT' | B | R(a) = exc
| OP_RESCUE" | BB | R(b) = R(a).isa?(R(b))
| OP_POPERR | B | a.times{rescue_pop()}
| OP_RAISE' | B | raise(R(a))
| OP_EPUSH' | B | ensure_push(SEQ[a])
| OP_EPOP | B | A.times{ensure_pop().call}
| OP_SENDV" | BB | R(a) = call(R(a),Syms(b),*R(a+1))
| OP_SENDVB" | BB | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2))
| OP_SEND" | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c))
| OP_SENDB" | BBB | R(a) = call(R(a),Syms(Bx),R(a+1),...,R(a+c),&R(a+c+1))
| OP_CALL' | B | R(a) = self.call(frame.argc, frame.argv)
| OP_SUPER' | BB | R(a) = super(R(a+1),... ,R(a+b+1))
| OP_ARGARY' | BS | R(a) = argument array (16=5:1:5:1:4)
| OP_ENTER | W | arg setup according to flags (23=5:5:1:5:5:1:1)
| OP_KARG" | BB | R(a) = kdict[Syms(Bx)] # todo
| OP_KARG2" | BB | R(a) = kdict[Syms(Bx)]; kdict.rm(Syms(b)) # todo
| OP_RETURN' | B | return R(a) (normal)
| OP_RETURN_BLK' | B | return R(a) (in-block return)
| OP_BREAK' | B | break R(a)
| OP_BLKPUSH' | BS | R(a) = block (16=5:1:5:1:4)
| OP_ADD" | BB | R(a) = R(a)+R(a+1)
| OP_ADDI" | BBB | R(a) = R(a)+mrb_int(c)
| OP_SUB" | BB | R(a) = R(a)-R(a+1)
| OP_SUBI" | BB | R(a) = R(a)-C
| OP_MUL" | BB | R(a) = R(a)*R(a+1)
| OP_DIV" | BB | R(a) = R(a)/R(a+1)
| OP_EQ" | BB | R(a) = R(a)==R(a+1)
| OP_LT" | BB | R(a) = R(a)<R(a+1)
| OP_LE" | BB | R(a) = R(a)<=R(a+1)
| OP_GT" | BB | R(a) = R(a)>R(a+1)
| OP_GE" | BB | R(a) = R(a)>=R(a+1)
| OP_ARRAY' | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b))
| OP_ARRAY2" | BB | R(a) = ary_new(R(b),R(b+1)..R(b+c))
| OP_ARYCAT' | B | ary_cat(R(a),R(a+1))
| OP_ARYPUSH' | B | ary_push(R(a),R(a+1))
| OP_AREF' | BB | R(a) = R(a)[b]
| OP_ASET' | BB | R(a)[b] = R(a+1)
| OP_APOST' | BB | *R(a),R(A+1)..R(A+C) = R(a)[B..]
| OP_STRING" | BB | R(a) = str_dup(Lit(b))
| OP_STRCAT' | B | str_cat(R(a),R(a+1))
| OP_HASH' | BB | R(a) = hash_new(R(a),R(a+1)..R(a+b))
| OP_HASHADD' | BB | R(a) = hash_push(R(a),R(a+1)..R(a+b))
| OP_LAMBDA" | BB | R(a) = lambda(SEQ[b],OP_L_LAMBDA)
| OP_BLOCK" | BB | R(a) = lambda(SEQ[b],OP_L_BLOCK)
| OP_METHOD" | BB | R(a) = lambda(SEQ[b],OP_L_METHOD)
| OP_RANGE_INC' | B | R(a) = range_new(R(a),R(a+1),FALSE)
| OP_RANGE_EXC' | B | R(a) = range_new(R(a),R(a+1),TRUE)
| OP_OCLASS' | B | R(a) = ::Object
| OP_CLASS" | BB | R(a) = newclass(R(a),Syms(b),R(a+1))
| OP_MODULE" | BB | R(a) = newmodule(R(a),Syms(b))
| OP_EXEC" | BB | R(a) = blockexec(R(a),SEQ[b])
| OP_DEF" | BB | R(a).newmethod(Syms(b),R(a+1))
| OP_ALIAS' | B | alias_method(R(a),R(a+1),R(a+2))
| OP_UNDEF" | BB | undef_method(R(a),Syms(b))
| OP_SCLASS' | B | R(a) = R(a).singleton_class
| OP_TCLASS' | B | R(a) = target_class
| OP_ERR' | B | raise(RuntimeError, Lit(Bx))
| OP_EXT1 | - | make 1st operand 16bit
| OP_EXT2 | - | make 2nd operand 16bit
| OP_EXT3 | - | make 1st and 2nd operands 16bit
| OP_STOP | - | stop VM
| Instruction Name | Operand type | Semantics |
|------------------|--------------|--------------------------------------------------------|
| OP_NOP | - | no operation |
| OP_MOVE" | BB | R(a) = R(b) |
| OP_LOADL" | BB | R(a) = Pool(b) |
| OP_LOADI" | BB | R(a) = mrb_int(b) |
| OP_LOADINEG" | BB | R(a) = mrb_int(-b) |
| OP_LOADI__1' | B | R(a) = mrb_int(-1) |
| OP_LOADI_0' | B | R(a) = mrb_int(0) |
| OP_LOADI_1' | B | R(a) = mrb_int(1) |
| OP_LOADI_2' | B | R(a) = mrb_int(2) |
| OP_LOADI_3' | B | R(a) = mrb_int(3) |
| OP_LOADI_4' | B | R(a) = mrb_int(4) |
| OP_LOADI_5' | B | R(a) = mrb_int(5) |
| OP_LOADI_6' | B | R(a) = mrb_int(6) |
| OP_LOADI_7' | B | R(a) = mrb_int(7) |
| OP_LOADI16' | BsS | R(a) = mrb_int(b) |
| OP_LOADSYM" | BB | R(a) = Syms(b) |
| OP_LOADNIL' | B | R(a) = nil |
| OP_LOADSELF' | B | R(a) = self |
| OP_LOADT' | B | R(a) = true |
| OP_LOADF' | B | R(a) = false |
| OP_GETGV" | BB | R(a) = getglobal(Syms(b)) |
| OP_SETGV" | BB | setglobal(Syms(b), R(a)) |
| OP_GETSV" | BB | R(a) = Special[Syms(b)] |
| OP_SETSV" | BB | Special[Syms(b)] = R(a) |
| OP_GETIV" | BB | R(a) = ivget(Syms(b)) |
| OP_SETIV" | BB | ivset(Syms(b),R(a)) |
| OP_GETCV" | BB | R(a) = cvget(Syms(b)) |
| OP_SETCV" | BB | cvset(Syms(b),R(a)) |
| OP_GETCONST" | BB | R(a) = constget(Syms(b)) |
| OP_SETCONST" | BB | constset(Syms(b),R(a)) |
| OP_GETMCNST" | BB | R(a) = R(a)::Syms(b) |
| OP_SETMCNST" | BB | R(a+1)::Syms(b) = R(a) |
| OP_GETUPVAR" | BBB | R(a) = uvget(b,c) |
| OP_SETUPVAR" | BBB | uvset(b,c,R(a)) |
| OP_JMP | S | pc=a |
| OP_JMPIF' | BS | if R(a) pc=b |
| OP_JMPNOT' | BS | if !R(a) pc=b |
| OP_JMPNIL' | BS | if R(a)==nil pc=b |
| OP_ONERR | S | rescue_push(a) |
| OP_EXCEPT' | B | R(a) = exc |
| OP_RESCUE" | BB | R(b) = R(a).isa?(R(b)) |
| OP_POPERR' | B | a.times{rescue_pop()} |
| OP_RAISE' | B | raise(R(a)) |
| OP_EPUSH' | B | ensure_push(SEQ[a]) |
| OP_EPOP' | B | A.times{ensure_pop().call} |
| OP_SENDV" | BB | R(a) = call(R(a),Syms(b),*R(a+1)) |
| OP_SENDVB" | BB | R(a) = call(R(a),Syms(b),*R(a+1),&R(a+2)) |
| OP_SEND" | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c)) |
| OP_SENDB" | BBB | R(a) = call(R(a),Syms(b),R(a+1),...,R(a+c),&R(a+c+1)) |
| OP_CALL | - | R(0) = self.call(frame.argc, frame.argv) |
| OP_SUPER" | BB | R(a) = super(R(a+1),... ,R(a+b+1)) |
| OP_ARGARY' | BS | R(a) = argument array (16=5:1:5:1:4) |
| OP_ENTER | W | arg setup according to flags (23=5:5:1:5:5:1:1) |
| OP_KEY_P" | BB | R(a) = kdict.key?(Syms(b)) |
| OP_KEYEND | - | raise unless kdict.empty? |
| OP_KARG" | BB | R(a) = kdict[Syms(b)]; kdict.delete(Syms(b)) |
| OP_RETURN' | B | return R(a) (normal) |
| OP_RETURN_BLK' | B | return R(a) (in-block return) |
| OP_BREAK' | B | break R(a) |
| OP_BLKPUSH' | BS | R(a) = block (16=5:1:5:1:4) |
| OP_ADD' | B | R(a) = R(a)+R(a+1) |
| OP_ADDI" | BB | R(a) = R(a)+mrb_int(b) |
| OP_SUB' | B | R(a) = R(a)-R(a+1) |
| OP_SUBI" | BB | R(a) = R(a)-mrb_int(b) |
| OP_MUL' | B | R(a) = R(a)*R(a+1) |
| OP_DIV' | B | R(a) = R(a)/R(a+1) |
| OP_EQ' | B | R(a) = R(a)==R(a+1) |
| OP_LT' | B | R(a) = R(a)<R(a+1) |
| OP_LE' | B | R(a) = R(a)<=R(a+1) |
| OP_GT' | B | R(a) = R(a)>R(a+1) |
| OP_GE' | B | R(a) = R(a)>=R(a+1) |
| OP_ARRAY" | BB | R(a) = ary_new(R(a),R(a+1)..R(a+b)) |
| OP_ARRAY2" | BBB | R(a) = ary_new(R(b),R(b+1)..R(b+c)) |
| OP_ARYCAT' | B | ary_cat(R(a),R(a+1)) |
| OP_ARYPUSH' | B | ary_push(R(a),R(a+1)) |
| OP_ARYDUP' | B | R(a) = ary_dup(R(a)) |
| OP_AREF" | BBB | R(a) = R(b)[c] |
| OP_ASET" | BBB | R(a)[c] = R(b) |
| OP_APOST" | BBB | *R(a),R(a+1)..R(a+c) = R(a)[b..] |
| OP_INTERN' | B | R(a) = intern(R(a)) |
| OP_STRING" | BB | R(a) = str_dup(Lit(b)) |
| OP_STRCAT' | B | str_cat(R(a),R(a+1)) |
| OP_HASH" | BB | R(a) = hash_new(R(a),R(a+1)..R(a+b)) |
| OP_HASHADD" | BB | R(a) = hash_push(R(a),R(a+1)..R(a+b)) |
| OP_HASHCAT' | B | R(a) = hash_cat(R(a),R(a+1)) |
| OP_LAMBDA" | BB | R(a) = lambda(SEQ[b],OP_L_LAMBDA) |
| OP_BLOCK" | BB | R(a) = lambda(SEQ[b],OP_L_BLOCK) |
| OP_METHOD" | BB | R(a) = lambda(SEQ[b],OP_L_METHOD) |
| OP_RANGE_INC' | B | R(a) = range_new(R(a),R(a+1),FALSE) |
| OP_RANGE_EXC' | B | R(a) = range_new(R(a),R(a+1),TRUE) |
| OP_OCLASS' | B | R(a) = ::Object |
| OP_CLASS" | BB | R(a) = newclass(R(a),Syms(b),R(a+1)) |
| OP_MODULE" | BB | R(a) = newmodule(R(a),Syms(b)) |
| OP_EXEC" | BB | R(a) = blockexec(R(a),SEQ[b]) |
| OP_DEF" | BB | R(a).newmethod(Syms(b),R(a+1)) |
| OP_ALIAS" | BB | alias_method(target_class,Syms(a),Syms(b)) |
| OP_UNDEF' | B | undef_method(target_class,Syms(a)) |
| OP_SCLASS' | B | R(a) = R(a).singleton_class |
| OP_TCLASS' | B | R(a) = target_class |
| OP_DEBUG" | BBB | print a,b,c |
| OP_ERR' | B | raise(LocalJumpError, Lit(a)) |
| OP_EXT1 | - | make 1st operand 16bit |
| OP_EXT2 | - | make 2nd operand 16bit |
| OP_EXT3 | - | make 1st and 2nd operands 16bit |
| OP_STOP | - | stop VM |
|------------------|--------------|--------------------------------------------------------|
+2 -2
View File
@@ -42,7 +42,7 @@ MRuby::CrossBuild.new("ArduinoDue") do |conf|
cc.flags = %w(-g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500
-Dprintf=iprintf -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=156 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM
-D__SAM3X8E__ -mthumb -DUSB_PID=0x003e -DUSB_VID=0x2341 -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due")
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
#configuration for low memory environment
cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
@@ -64,7 +64,7 @@ MRuby::CrossBuild.new("ArduinoDue") do |conf|
conf.archiver do |archiver|
archiver.command = "#{BIN_PATH}/arm-none-eabi-ar"
archiver.archive_options = 'rcs %{outfile} %{objs}'
archiver.archive_options = 'rcs "%{outfile}" %{objs}'
end
#no executables
+2 -2
View File
@@ -32,7 +32,7 @@ MRuby::CrossBuild.new('core2-32-poky-linux') do |conf|
cc.flags = %w(-m32 -march=core2 -mtune=core2 -msse3 -mfpmath=sse -mstackrealign -fno-omit-frame-pointer)
cc.flags << %w(-O2 -pipe -g -feliminate-unused-debug-types)
cc.flags << "--sysroot=#{POKY_EDISON_SYSROOT}"
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
cc.defines = %w(ENABLE_READLINE)
end
@@ -47,7 +47,7 @@ MRuby::CrossBuild.new('core2-32-poky-linux') do |conf|
conf.archiver do |archiver|
archiver.command = "#{POKY_EDISON_BIN_PATH}/i586-poky-linux-ar"
archiver.archive_options = 'rcs %{outfile} %{objs}'
archiver.archive_options = 'rcs "%{outfile}" %{objs}'
end
conf.linker do |linker|
@@ -39,7 +39,7 @@ MRuby::CrossBuild.new("Galileo") do |conf|
cc.flags = %w(-m32 -march=i586 -c -g -Os -w
-ffunction-sections -fdata-sections -MMD -DARDUINO=153)
cc.flags << "--sysroot=#{GALILEO_SYSROOT}"
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
end
conf.cxx do |cxx|
@@ -54,7 +54,7 @@ MRuby::CrossBuild.new("Galileo") do |conf|
conf.archiver do |archiver|
archiver.command = "#{GALILEO_BIN_PATH}/i586-poky-linux-uclibc-ar"
archiver.archive_options = 'rcs %{outfile} %{objs}'
archiver.archive_options = 'rcs "%{outfile}" %{objs}'
end
conf.linker do |linker|
+2 -2
View File
@@ -27,7 +27,7 @@ MRuby::CrossBuild.new("RX630") do |conf|
conf.cc do |cc|
cc.command = "#{BIN_PATH}/rx-elf-gcc"
cc.flags = "-Wall -g -O2 -flto -mcpu=rx600 -m64bit-doubles"
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
#configuration for low memory environment
cc.defines << %w(MRB_USE_FLOAT)
@@ -53,7 +53,7 @@ MRuby::CrossBuild.new("RX630") do |conf|
conf.archiver do |archiver|
archiver.command = "#{BIN_PATH}/rx-elf-ar"
archiver.archive_options = 'rcs %{outfile} %{objs}'
archiver.archive_options = 'rcs "%{outfile}" %{objs}'
end
#no executables
@@ -39,7 +39,7 @@ MRuby::CrossBuild.new("chipKITMax32") do |conf|
cc.flags = %w(-O2 -mno-smart-io -w -ffunction-sections -fdata-sections -g -mdebugger -Wcast-align
-fno-short-double -mprocessor=32MX795F512L -DF_CPU=80000000L -DARDUINO=23 -D_BOARD_MEGA_
-DMPIDEVER=0x01000202 -DMPIDE=23)
cc.compile_options = "%{flags} -o %{outfile} -c %{infile}"
cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
#configuration for low memory environment
cc.defines << %w(MRB_HEAP_PAGE_SIZE=64)
@@ -60,7 +60,7 @@ MRuby::CrossBuild.new("chipKITMax32") do |conf|
conf.archiver do |archiver|
archiver.command = "#{PIC32_PATH}/compiler/pic32-tools/bin/pic32-ar"
archiver.archive_options = 'rcs %{outfile} %{objs}'
archiver.archive_options = 'rcs "%{outfile}" %{objs}'
end
#no executables
@@ -0,0 +1,108 @@
MRuby::Build.new do |conf|
# Gets set by the VS command prompts
if ENV['VisualStudioVersion'] || ENV['VSINSTALLDIR']
toolchain :visualcpp
else
toolchain :gcc
end
enable_debug
# Include the default GEMs
conf.gembox 'default'
end
# Cross Compiling configuration for the Sega Dreamcast
# This configuration requires KallistiOS (KOS)
# https://dreamcast.wiki
#
# Tested on GNU/Linux, MinGW-w64/MSYS2, Cygwin, macOS and MinGW/MSYS (see below)
#
MRuby::CrossBuild.new("dreamcast") do |conf|
toolchain :gcc
# Support for DreamSDK (based on MinGW/MSYS)
# To compile mruby with DreamSDK, RubyInstaller for Windows should be installed
DREAMSDK_HOME = ENV["DREAMSDK_HOME"]
MSYS_ROOT = !(DREAMSDK_HOME.nil? || DREAMSDK_HOME.empty?) ? "#{DREAMSDK_HOME}/msys/1.0" : ""
# Setting paths
DREAMCAST_PATH = "#{MSYS_ROOT}/opt/toolchains/dc"
KOS_PATH = "#{DREAMCAST_PATH}/kos"
BIN_PATH = "#{DREAMCAST_PATH}/sh-elf/bin"
# C compiler
# Flags were extracted from KallistiOS environment files
conf.cc do |cc|
cc.command = "#{BIN_PATH}/sh-elf-gcc"
cc.include_paths << ["#{KOS_PATH}/include", "#{KOS_PATH}/kernel/arch/dreamcast/include", "#{KOS_PATH}/addons/include", "#{KOS_PATH}/../kos-ports/include"]
cc.flags << ["-O2", "-fomit-frame-pointer", "-ml", "-m4-single-only", "-ffunction-sections", "-fdata-sections", "-Wall", "-g", "-fno-builtin", "-ml", "-m4-single-only", "-Wl,-Ttext=0x8c010000", "-Wl,--gc-sections", "-T#{KOS_PATH}/utils/ldscripts/shlelf.xc", "-nodefaultlibs"]
cc.compile_options = %Q[%{flags} -o "%{outfile}" -c "%{infile}"]
cc.defines << %w(_arch_dreamcast)
cc.defines << %w(_arch_sub_pristine)
end
# C++ compiler
conf.cxx do |cxx|
cxx.command = conf.cc.command.dup
cxx.include_paths = conf.cc.include_paths.dup
cxx.flags = conf.cc.flags.dup
cxx.flags << %w(-fno-rtti -fno-exceptions)
cxx.defines = conf.cc.defines.dup
cxx.compile_options = conf.cc.compile_options.dup
end
# Linker
# There is an issue when making the mruby library with KallistiOS:
# 'newlib_kill.o' and 'newlib_getpid.o' aren't found so they are explicitly
# specified here at least for now.
conf.linker do |linker|
linker.command="#{BIN_PATH}/sh-elf-gcc"
linker.flags << ["#{MSYS_ROOT}/opt/toolchains/dc/kos/kernel/build/newlib_kill.o", "#{MSYS_ROOT}/opt/toolchains/dc/kos/kernel/build/newlib_getpid.o", "-Wl,--start-group -lkallisti -lc -lgcc -Wl,--end-group"]
linker.library_paths << ["#{KOS_PATH}/lib/dreamcast", "#{KOS_PATH}/addons/lib/dreamcast", "#{KOS_PATH}/../kos-ports/lib"]
end
# Archiver
conf.archiver do |archiver|
archiver.command = "#{BIN_PATH}/sh-elf-ar"
archiver.archive_options = 'rcs "%{outfile}" %{objs}'
end
# No executables
conf.bins = []
# Do not build executable test
conf.build_mrbtest_lib_only
# Disable C++ exception
conf.disable_cxx_exception
# Gems from core
# removing mruby-io
conf.gem :core => "mruby-metaprog"
conf.gem :core => "mruby-pack"
conf.gem :core => "mruby-sprintf"
conf.gem :core => "mruby-print"
conf.gem :core => "mruby-math"
conf.gem :core => "mruby-time"
conf.gem :core => "mruby-struct"
conf.gem :core => "mruby-compar-ext"
conf.gem :core => "mruby-enum-ext"
conf.gem :core => "mruby-string-ext"
conf.gem :core => "mruby-numeric-ext"
conf.gem :core => "mruby-array-ext"
conf.gem :core => "mruby-hash-ext"
conf.gem :core => "mruby-range-ext"
conf.gem :core => "mruby-proc-ext"
conf.gem :core => "mruby-symbol-ext"
conf.gem :core => "mruby-random"
conf.gem :core => "mruby-object-ext"
conf.gem :core => "mruby-objectspace"
conf.gem :core => "mruby-fiber"
conf.gem :core => "mruby-enumerator"
conf.gem :core => "mruby-enum-lazy"
conf.gem :core => "mruby-toplevel-ext"
conf.gem :core => "mruby-kernel-ext"
conf.gem :core => "mruby-class-ext"
conf.gem :core => "mruby-compiler"
end
+10 -10
View File
@@ -38,21 +38,24 @@
/* add -DMRB_METHOD_T_STRUCT on machines that use higher bits of pointers */
/* no MRB_METHOD_T_STRUCT requires highest 2 bits of function pointers to be zero */
//#define MRB_METHOD_T_STRUCT
#ifndef MRB_METHOD_T_STRUCT
// can't use highest 2 bits of function pointers at least on 32bit
// Windows and 32bit Linux.
# ifdef MRB_32BIT
# define MRB_METHOD_T_STRUCT
# endif
#endif
/* add -DMRB_INT16 to use 16bit integer for mrb_int; conflict with MRB_INT32 and MRB_INT64 */
//#define MRB_INT16
/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT16 and MRB_INT64;
/* add -DMRB_INT32 to use 32bit integer for mrb_int; conflict with MRB_INT64;
Default for 32-bit CPU mode. */
//#define MRB_INT32
/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT16 and MRB_INT32;
/* add -DMRB_INT64 to use 64bit integer for mrb_int; conflict with MRB_INT32;
Default for 64-bit CPU mode. */
//#define MRB_INT64
/* if no specific integer type is chosen */
#if !defined(MRB_INT16) && !defined(MRB_INT32) && !defined(MRB_INT64)
#if !defined(MRB_INT32) && !defined(MRB_INT64)
# if defined(MRB_64BIT) && !defined(MRB_NAN_BOXING)
/* Use 64bit integers on 64bit architecture (without MRB_NAN_BOXING) */
# define MRB_INT64
@@ -62,9 +65,6 @@
# endif
#endif
#define MRB_COMPLEX_NUMBERS
#define MRB_RATIONAL_NUMBERS
/* define on big endian machines; used by MRB_NAN_BOXING, etc. */
#ifndef MRB_ENDIAN_BIG
# if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \
+25 -9
View File
@@ -1,7 +1,7 @@
/*
** mruby - An embeddable Ruby implementation
**
** Copyright (c) mruby developers 2010-2019
** Copyright (c) mruby developers 2010-2020
**
** Permission is hereby granted, free of charge, to any person obtaining
** a copy of this software and associated documentation files (the
@@ -70,7 +70,13 @@
#include "mrbconf.h"
#include <mruby/common.h>
#include <mruby/value.h>
#include <mruby/gc.h>
#include <mruby/version.h>
#ifndef MRB_WITHOUT_FLOAT
#include <float.h>
#ifndef FLT_EPSILON
#define FLT_EPSILON (1.19209290e-07f)
#endif
@@ -88,11 +94,6 @@
#endif
#endif
#include <mruby/common.h>
#include <mruby/value.h>
#include <mruby/gc.h>
#include <mruby/version.h>
/**
* MRuby C API entry point
*/
@@ -164,8 +165,8 @@ struct mrb_context {
struct RProc **ensure; /* ensure handler stack */
uint16_t esize, eidx;
enum mrb_fiber_state status;
mrb_bool vmexec;
enum mrb_fiber_state status : 4;
mrb_bool vmexec : 1;
struct RFiber *fib;
};
@@ -317,7 +318,9 @@ MRB_API struct RClass *mrb_define_class(mrb_state *mrb, const char *name, struct
* @return [struct RClass *] Reference to the newly defined module.
*/
MRB_API struct RClass *mrb_define_module(mrb_state *mrb, const char *name);
MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value val);
MRB_API struct RClass *mrb_singleton_class_ptr(mrb_state *mrb, mrb_value val);
/**
* Include a module in another class or module.
@@ -956,8 +959,21 @@ mrb_get_mid(mrb_state *mrb) /* get method symbol */
*/
MRB_API mrb_int mrb_get_argc(mrb_state *mrb);
/**
* Retrieve an array of arguments from mrb_state.
*
* Correctly handles *splat arguments.
*/
MRB_API mrb_value* mrb_get_argv(mrb_state *mrb);
/**
* Retrieve the first and only argument from mrb_state.
* Raises ArgumentError unless the number of arguments is exactly one.
*
* Correctly handles *splat arguments.
*/
MRB_API mrb_value mrb_get_arg1(mrb_state *mrb);
/* `strlen` for character string literals (use with caution or `strlen` instead)
Adjacent string literals are concatenated in C/C++ in translation phase 6.
If `lit` is not one, the compiler will report a syntax error:
@@ -1148,7 +1164,6 @@ MRB_API void mrb_close(mrb_state *mrb);
MRB_API void* mrb_default_allocf(mrb_state*, void*, size_t, void*);
MRB_API mrb_value mrb_top_self(mrb_state *mrb);
MRB_API mrb_value mrb_run(mrb_state *mrb, struct RProc* proc, mrb_value self);
MRB_API mrb_value mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
MRB_API mrb_value mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep);
MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *iseq);
@@ -1232,6 +1247,7 @@ MRB_API mrb_noreturn void mrb_raise(mrb_state *mrb, struct RClass *c, const char
MRB_API mrb_noreturn void mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...);
MRB_API mrb_noreturn void mrb_name_error(mrb_state *mrb, mrb_sym id, const char *fmt, ...);
MRB_API mrb_noreturn void mrb_frozen_error(mrb_state *mrb, void *frozen_obj);
MRB_API mrb_noreturn void mrb_argnum_error(mrb_state *mrb, mrb_int argc, int min, int max);
MRB_API void mrb_warn(mrb_state *mrb, const char *fmt, ...);
MRB_API mrb_noreturn void mrb_bug(mrb_state *mrb, const char *fmt, ...);
MRB_API void mrb_print_backtrace(mrb_state *mrb);
+7 -3
View File
@@ -17,7 +17,7 @@ MRB_BEGIN_DECL
typedef struct mrb_shared_array {
int refcnt;
mrb_int len;
mrb_ssize len;
mrb_value *ptr;
} mrb_shared_array;
@@ -26,9 +26,9 @@ struct RArray {
MRB_OBJECT_HEADER;
union {
struct {
mrb_int len;
mrb_ssize len;
union {
mrb_int capa;
mrb_ssize capa;
mrb_shared_array *shared;
} aux;
mrb_value *ptr;
@@ -239,6 +239,7 @@ MRB_API mrb_value mrb_ary_entry(mrb_value ary, mrb_int offset);
* @param head Beginning position of a replacement subsequence.
* @param len Length of a replacement subsequence.
* @param rpl The array of replacement elements.
* It is possible to pass `mrb_undef_value()` instead of an empty array.
* @return The receiver array.
*/
MRB_API mrb_value mrb_ary_splice(mrb_state *mrb, mrb_value self, mrb_int head, mrb_int len, mrb_value rpl);
@@ -291,6 +292,9 @@ MRB_API mrb_value mrb_ary_join(mrb_state *mrb, mrb_value ary, mrb_value sep);
*/
MRB_API mrb_value mrb_ary_resize(mrb_state *mrb, mrb_value ary, mrb_int new_len);
/* helper functions */
mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
MRB_END_DECL
#endif /* MRUBY_ARRAY_H */
+12 -2
View File
@@ -20,6 +20,7 @@
#endif
#define MRB_FIXNUM_SHIFT 0
#define MRB_SYMBOL_SHIFT 0
/* value representation by nan-boxing:
* float : FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF
@@ -43,6 +44,9 @@ typedef struct mrb_value {
};
)
};
#ifdef MRB_64BIT
struct RCptr *vp;
#endif
} value;
};
} mrb_value;
@@ -53,13 +57,15 @@ typedef struct mrb_value {
#define mrb_type(o) (enum mrb_vtype)((uint32_t)0xfff00000 < (o).value.ttt ? mrb_tt(o) : MRB_TT_FLOAT)
#define mrb_ptr(o) ((void*)((((uintptr_t)0x3fffffffffff)&((uintptr_t)((o).value.p)))<<2))
#define mrb_float(o) (o).f
#define mrb_cptr(o) mrb_ptr(o)
#define mrb_fixnum(o) (o).value.i
#define mrb_symbol(o) (o).value.sym
#ifdef MRB_64BIT
MRB_API mrb_value mrb_nan_boxing_cptr_value(struct mrb_state*, void*);
#define mrb_cptr(o) (((struct RCptr*)mrb_ptr(o))->p)
#define BOXNAN_SHIFT_LONG_POINTER(v) (((uintptr_t)(v)>>34)&0x3fff)
#else
#define mrb_cptr(o) ((o).value.p)
#define BOXNAN_SHIFT_LONG_POINTER(v) 0
#endif
@@ -89,7 +95,11 @@ typedef struct mrb_value {
#define SET_INT_VALUE(r,n) BOXNAN_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
#define SET_SYM_VALUE(r,v) BOXNAN_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
#define SET_OBJ_VALUE(r,v) BOXNAN_SET_OBJ_VALUE(r, (((struct RObject*)(v))->tt), (v))
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_OBJ_VALUE(r, MRB_TT_CPTR, v)
#ifdef MRB_64BIT
#define SET_CPTR_VALUE(mrb,r,v) ((r) = mrb_nan_boxing_cptr_value(mrb, v))
#else
#define SET_CPTR_VALUE(mrb,r,v) BOXNAN_SET_VALUE(r, MRB_TT_CPTR, value.p, v)
#endif
#define SET_UNDEF_VALUE(r) BOXNAN_SET_VALUE(r, MRB_TT_UNDEF, value.i, 0)
#endif /* MRUBY_BOXING_NAN_H */
+1
View File
@@ -8,6 +8,7 @@
#define MRUBY_BOXING_NO_H
#define MRB_FIXNUM_SHIFT 0
#define MRB_SYMBOL_SHIFT 0
union mrb_value_union {
#ifndef MRB_WITHOUT_FLOAT
+28 -33
View File
@@ -7,10 +7,6 @@
#ifndef MRUBY_BOXING_WORD_H
#define MRUBY_BOXING_WORD_H
#if defined(MRB_INT16)
# error MRB_INT16 is too small for MRB_WORD_BOXING.
#endif
#if defined(MRB_INT64) && !defined(MRB_64BIT)
#error MRB_INT64 cannot be used with MRB_WORD_BOXING in 32-bit mode.
#endif
@@ -22,11 +18,6 @@ struct RFloat {
};
#endif
struct RCptr {
MRB_OBJECT_HEADER;
void *p;
};
enum mrb_special_consts {
MRB_Qnil = 0,
MRB_Qfalse = 4,
@@ -34,41 +25,46 @@ enum mrb_special_consts {
MRB_Qundef = 20,
};
#define MRB_FIXNUM_SHIFT 1
#define MRB_SYMBOL_SHIFT 2
#define MRB_FIXNUM_FLAG (1 << (MRB_FIXNUM_SHIFT - 1))
#define MRB_SYMBOL_FLAG (1 << (MRB_SYMBOL_SHIFT - 1))
#define MRB_FIXNUM_MASK ((1 << MRB_FIXNUM_SHIFT) - 1)
#define MRB_SYMBOL_MASK ((1 << MRB_SYMBOL_SHIFT) - 1)
#define MRB_IMMEDIATE_MASK 0x07
#ifdef MRB_64BIT
#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT)
#define MRB_SYMBOL_MAX UINT32_MAX
#if defined(MRB_64BIT) && defined(MRB_INT32)
#define MRB_FIXNUM_SHIFT 0
#else
#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT)
#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT)
#define MRB_FIXNUM_SHIFT BOXWORD_FIXNUM_SHIFT
#endif
#define MRB_SYMBOL_SHIFT BOXWORD_SYMBOL_SHIFT
#define BOXWORD_FIXNUM_BIT_POS 1
#define BOXWORD_SYMBOL_BIT_POS 2
#define BOXWORD_FIXNUM_SHIFT BOXWORD_FIXNUM_BIT_POS
#ifdef MRB_64BIT
#define BOXWORD_SYMBOL_SHIFT 0
#else
#define BOXWORD_SYMBOL_SHIFT BOXWORD_SYMBOL_BIT_POS
#endif
#define BOXWORD_FIXNUM_FLAG (1 << (BOXWORD_FIXNUM_BIT_POS - 1))
#define BOXWORD_SYMBOL_FLAG (1 << (BOXWORD_SYMBOL_BIT_POS - 1))
#define BOXWORD_FIXNUM_MASK ((1 << BOXWORD_FIXNUM_BIT_POS) - 1)
#define BOXWORD_SYMBOL_MASK ((1 << BOXWORD_SYMBOL_BIT_POS) - 1)
#define BOXWORD_IMMEDIATE_MASK 0x07
#define BOXWORD_SHIFT_VALUE(o,n,t) \
((((t)(o).w)) >> MRB_##n##_SHIFT)
(t)(((long)(o).w) >> BOXWORD_##n##_SHIFT)
#define BOXWORD_SET_SHIFT_VALUE(o,n,v) \
((o).w = (((unsigned long)(v)) << MRB_##n##_SHIFT) | MRB_##n##_FLAG)
((o).w = (((unsigned long)(v)) << BOXWORD_##n##_SHIFT) | BOXWORD_##n##_FLAG)
#define BOXWORD_SHIFT_VALUE_P(o,n) \
(((o).w & MRB_##n##_MASK) == MRB_##n##_FLAG)
(((o).w & BOXWORD_##n##_MASK) == BOXWORD_##n##_FLAG)
#define BOXWORD_OBJ_TYPE_P(o,n) \
(!mrb_immediate_p(o) && (o).value.bp->tt == MRB_TT_##n)
/*
* mrb_value representation:
*
* nil : ...0000 0000 (all bits are zero)
* false : ...0000 0100
* nil : ...0000 0000 (all bits are 0)
* false : ...0000 0100 (mrb_fixnum(v) != 0)
* true : ...0000 1100
* undef : ...0001 0100
* fixnum: ...IIII III1
* symbol: ...SSSS SS10 (high-order 32-bit are symbol value in 64-bit mode)
* object: ...PPPP P000
* symbol: ...SSSS SS10 (use only upper 32-bit as symbol value on 64-bit CPU)
* object: ...PPPP P000 (any bits are 1)
*/
typedef union mrb_value {
union {
@@ -114,10 +110,10 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#endif
#define mrb_bool(o) (((o).w & ~(unsigned long)MRB_Qfalse) != 0)
#define mrb_immediate_p(o) ((o).w & MRB_IMMEDIATE_MASK || (o).w == MRB_Qnil)
#define mrb_immediate_p(o) ((o).w & BOXWORD_IMMEDIATE_MASK || (o).w == MRB_Qnil)
#define mrb_fixnum_p(o) BOXWORD_SHIFT_VALUE_P(o, FIXNUM)
#ifdef MRB_64BIT
#define mrb_symbol_p(o) ((o).value.sym_flag == MRB_SYMBOL_FLAG)
#define mrb_symbol_p(o) ((o).value.sym_flag == BOXWORD_SYMBOL_FLAG)
#else
#define mrb_symbol_p(o) BOXWORD_SHIFT_VALUE_P(o, SYMBOL)
#endif
@@ -141,7 +137,6 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#define mrb_sclass_p(o) BOXWORD_OBJ_TYPE_P(o, SCLASS)
#define mrb_proc_p(o) BOXWORD_OBJ_TYPE_P(o, PROC)
#define mrb_range_p(o) BOXWORD_OBJ_TYPE_P(o, RANGE)
#define mrb_file_p(o) BOXWORD_OBJ_TYPE_P(o, FILE)
#define mrb_env_p(o) BOXWORD_OBJ_TYPE_P(o, ENV)
#define mrb_data_p(o) BOXWORD_OBJ_TYPE_P(o, DATA)
#define mrb_fiber_p(o) BOXWORD_OBJ_TYPE_P(o, FIBER)
@@ -159,7 +154,7 @@ MRB_API mrb_value mrb_word_boxing_float_pool(struct mrb_state*, mrb_float);
#define SET_BOOL_VALUE(r,b) ((b) ? SET_TRUE_VALUE(r) : SET_FALSE_VALUE(r))
#define SET_INT_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, FIXNUM, n)
#ifdef MRB_64BIT
#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = MRB_SYMBOL_FLAG)
#define SET_SYM_VALUE(r,v) ((r).value.sym = v, (r).value.sym_flag = BOXWORD_SYMBOL_FLAG)
#else
#define SET_SYM_VALUE(r,n) BOXWORD_SET_SHIFT_VALUE(r, SYMBOL, n)
#endif
+7
View File
@@ -90,10 +90,17 @@ mrb_value mrb_instance_new(mrb_state *mrb, mrb_value cv);
void mrb_class_name_class(mrb_state*, struct RClass*, struct RClass*, mrb_sym);
mrb_bool mrb_const_name_p(mrb_state*, const char*, mrb_int);
mrb_value mrb_class_find_path(mrb_state*, struct RClass*);
mrb_value mrb_mod_to_s(mrb_state*, mrb_value);
void mrb_gc_mark_mt(mrb_state*, struct RClass*);
size_t mrb_gc_mark_mt_size(mrb_state*, struct RClass*);
void mrb_gc_free_mt(mrb_state*, struct RClass*);
#ifdef MRB_METHOD_CACHE
void mrb_mc_clear_by_class(mrb_state *mrb, struct RClass* c);
#else
#define mrb_mc_clear_by_class(mrb,c)
#endif
MRB_END_DECL
#endif /* MRUBY_CLASS_H */
+10
View File
@@ -74,6 +74,16 @@ MRB_BEGIN_DECL
#endif
#endif
/** Declare mingw versions */
#if defined(__MINGW32__) || defined(__MINGW64__)
# include <_mingw.h>
# if defined(__MINGW64_VERSION_MAJOR)
# define MRB_MINGW64_VERSION (__MINGW64_VERSION_MAJOR * 1000 + __MINGW64_VERSION_MINOR)
# elif defined(__MINGW32_MAJOR_VERSION)
# define MRB_MINGW32_VERSION (__MINGW32_MAJOR_VERSION * 1000 + __MINGW32_MINOR_VERSION)
# endif
#endif
MRB_END_DECL
#endif /* MRUBY_COMMON_H */
+12 -3
View File
@@ -33,7 +33,7 @@ typedef struct mrbc_context {
mrb_bool no_exec:1;
mrb_bool keep_lv:1;
mrb_bool no_optimize:1;
mrb_bool on_eval:1;
struct RProc *upper;
size_t parser_nerr;
} mrbc_context;
@@ -151,8 +151,8 @@ struct mrb_parser_state {
mrb_ast_node *tree;
mrb_bool no_optimize:1;
mrb_bool on_eval:1;
mrb_bool capture_errors:1;
struct RProc *upper;
struct mrb_parser_message error_buffer[10];
struct mrb_parser_message warn_buffer[10];
@@ -161,6 +161,7 @@ struct mrb_parser_state {
uint16_t current_filename_index;
struct mrb_jmpbuf* jmp;
mrb_ast_node *nvars;
};
MRB_API struct mrb_parser_state* mrb_parser_new(mrb_state*);
@@ -179,7 +180,15 @@ MRB_API struct mrb_parser_state* mrb_parse_nstring(mrb_state*,const char*,size_t
MRB_API struct RProc* mrb_generate_code(mrb_state*, struct mrb_parser_state*);
MRB_API mrb_value mrb_load_exec(mrb_state *mrb, struct mrb_parser_state *p, mrbc_context *c);
/* program load functions */
/** program load functions
* Please note! Currently due to interactions with the GC calling these functions will
* leak one RProc object per function call.
* To prevent this save the current memory arena before calling and restore the arena
* right after, like so
* int ai = mrb_gc_arena_save(mrb);
* mrb_value status = mrb_load_string(mrb, buffer);
* mrb_gc_arena_restore(mrb, ai);
*/
#ifndef MRB_DISABLE_STDIO
MRB_API mrb_value mrb_load_file(mrb_state*,FILE*);
MRB_API mrb_value mrb_load_file_cxt(mrb_state*,FILE*, mrbc_context *cxt);
+1 -17
View File
@@ -17,10 +17,6 @@
MRB_BEGIN_DECL
#define DUMP_DEBUG_INFO 1
#define DUMP_ENDIAN_BIG 2
#define DUMP_ENDIAN_LIL 4
#define DUMP_ENDIAN_NAT 6
#define DUMP_ENDIAN_MASK 6
int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size);
#ifndef MRB_DISABLE_STDIO
@@ -52,8 +48,7 @@ MRB_API mrb_irep *mrb_read_irep_buf(mrb_state*, const void*, size_t);
/* Rite Binary File header */
#define RITE_BINARY_IDENT "RITE"
#define RITE_BINARY_IDENT_LIL "ETIR"
#define RITE_BINARY_FORMAT_VER "0006"
#define RITE_BINARY_FORMAT_VER "0007"
#define RITE_COMPILER_NAME "MATZ"
#define RITE_COMPILER_VERSION "0000"
@@ -106,17 +101,6 @@ struct rite_binary_footer {
RITE_SECTION_HEADER;
};
static inline int
bigendian_p()
{
int i;
char *p;
i = 1;
p = (char*)&i;
return p[0]?0:1;
}
static inline size_t
uint8_to_bin(uint8_t s, uint8_t *bin)
{
+1 -1
View File
@@ -52,7 +52,7 @@ mrb_break_value_get(struct RBreak *brk)
{
mrb_value val;
val.value = brk->value;
val.tt = brk->flags & RBREAK_VALUE_TT_MASK;
val.tt = (enum mrb_vtype)(brk->flags & RBREAK_VALUE_TT_MASK);
return val;
}
static inline void
+10
View File
@@ -49,6 +49,16 @@ typedef struct mrb_irep {
MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
/** load mruby bytecode functions
* Please note! Currently due to interactions with the GC calling these functions will
* leak one RProc object per function call.
* To prevent this save the current memory arena before calling and restore the arena
* right after, like so
* int ai = mrb_gc_arena_save(mrb);
* mrb_value status = mrb_load_irep(mrb, buffer);
* mrb_gc_arena_restore(mrb, ai);
*/
/* @param [const uint8_t*] irep code, expected as a literal */
MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*);
+4 -1
View File
@@ -21,7 +21,10 @@ MRB_BEGIN_DECL
struct RIStruct {
MRB_OBJECT_HEADER;
char inline_data[ISTRUCT_DATA_SIZE];
union {
intptr_t inline_alignment[3];
char inline_data[ISTRUCT_DATA_SIZE];
};
};
#define RISTRUCT(obj) ((struct RIStruct*)(mrb_ptr(obj)))
+23 -5
View File
@@ -73,6 +73,7 @@ static const uint8_t __m_either[] = {0x03, 0x0c, 0x30, 0xc0};
void kh_clear_##name(mrb_state *mrb, kh_##name##_t *h); \
khint_t kh_get_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key); \
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret); \
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h); \
void kh_resize_##name(mrb_state *mrb, kh_##name##_t *h, khint_t new_n_buckets); \
void kh_del_##name(mrb_state *mrb, kh_##name##_t *h, khint_t x); \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
@@ -95,16 +96,25 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
__hash_equal: hash comparation function
*/
#define KHASH_DEFINE(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \
void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \
mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); \
int kh_alloc_simple_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
khint_t sz = h->n_buckets; \
size_t len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \
uint8_t *p = (uint8_t*)mrb_malloc(mrb, sizeof(uint8_t)*sz/4+len*sz); \
uint8_t *p = (uint8_t*)mrb_malloc_simple(mrb, sizeof(uint8_t)*sz/4+len*sz); \
if (!p) { return 1; } \
h->size = h->n_occupied = 0; \
h->keys = (khkey_t *)p; \
h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \
h->ed_flags = p+len*sz; \
kh_fill_flags(h->ed_flags, 0xaa, sz/4); \
return 0; \
} \
void kh_alloc_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
if (kh_alloc_simple_##name(mrb, h)) { \
mrb_raise_nomemory(mrb); \
} \
} \
kh_##name##_t *kh_init_##name##_size(mrb_state *mrb, khint_t size) { \
kh_##name##_t *h = (kh_##name##_t*)mrb_calloc(mrb, 1, sizeof(kh_##name##_t)); \
@@ -112,7 +122,10 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
size = KHASH_MIN_SIZE; \
khash_power2(size); \
h->n_buckets = size; \
kh_alloc_##name(mrb, h); \
if (kh_alloc_simple_##name(mrb, h)) { \
mrb_free(mrb, h); \
mrb_raise_nomemory(mrb); \
} \
return h; \
} \
kh_##name##_t *kh_init_##name(mrb_state *mrb) { \
@@ -171,12 +184,16 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
mrb_free(mrb, old_keys); \
} \
} \
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
void kh_put_prepare_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
khint_t k, del_k, step = 0; \
if (h->n_occupied >= khash_upper_bound(h)) { \
kh_resize_##name(mrb, h, h->n_buckets*2); \
} \
} \
khint_t kh_put_##name(mrb_state *mrb, kh_##name##_t *h, khkey_t key, int *ret) \
{ \
khint_t k, del_k, step = 0; \
kh_put_prepare_##name(mrb, h); \
k = __hash_func(mrb,key) & khash_mask(h); \
del_k = kh_end(h); \
while (!__ac_isempty(h->ed_flags, k)) { \
@@ -239,6 +256,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len)
#define kh_destroy(name, mrb, h) kh_destroy_##name(mrb, h)
#define kh_clear(name, mrb, h) kh_clear_##name(mrb, h)
#define kh_resize(name, mrb, h, s) kh_resize_##name(mrb, h, s)
#define kh_put_prepare(name, mrb, h) kh_put_prepare_##name(mrb, h)
#define kh_put(name, mrb, h, k) kh_put_##name(mrb, h, k, NULL)
#define kh_put2(name, mrb, h, k, r) kh_put_##name(mrb, h, k, r)
#define kh_get(name, mrb, h, k) kh_get_##name(mrb, h, k)
+1
View File
@@ -37,6 +37,7 @@ MRB_API mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, mrb_int base);
/* ArgumentError if format string doesn't match /%(\.[0-9]+)?[aAeEfFgG]/ */
#ifndef MRB_WITHOUT_FLOAT
MRB_API mrb_value mrb_float_to_str(mrb_state *mrb, mrb_value x, const char *fmt);
MRB_API int mrb_float_to_cstr(mrb_state *mrb, char *buf, size_t len, const char *fmt, mrb_float f);
MRB_API mrb_float mrb_to_flo(mrb_state *mrb, mrb_value x);
MRB_API mrb_value mrb_int_value(mrb_state *mrb, mrb_float f);
#endif
+3 -2
View File
@@ -92,8 +92,8 @@ OPCODE(APOST, BBB) /* *R(a),R(a+1)..R(a+c) = R(a)[b..] */
OPCODE(INTERN, B) /* R(a) = intern(R(a)) */
OPCODE(STRING, BB) /* R(a) = str_dup(Lit(b)) */
OPCODE(STRCAT, B) /* str_cat(R(a),R(a+1)) */
OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b)) */
OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b)) */
OPCODE(HASH, BB) /* R(a) = hash_new(R(a),R(a+1)..R(a+b*2-1)) */
OPCODE(HASHADD, BB) /* R(a) = hash_push(R(a),R(a+1)..R(a+b*2)) */
OPCODE(HASHCAT, B) /* R(a) = hash_cat(R(a),R(a+1)) */
OPCODE(LAMBDA, BB) /* R(a) = lambda(SEQ[b],L_LAMBDA) */
OPCODE(BLOCK, BB) /* R(a) = lambda(SEQ[b],L_BLOCK) */
@@ -115,3 +115,4 @@ OPCODE(EXT1, Z) /* make 1st operand 16bit */
OPCODE(EXT2, Z) /* make 2nd operand 16bit */
OPCODE(EXT3, Z) /* make 1st and 2nd operands 16bit */
OPCODE(STOP, Z) /* stop VM */
OPCODE(LOADI16, BS) /* R(a) = mrb_int(b) */
+13 -8
View File
@@ -22,14 +22,19 @@ struct REnv {
mrb_sym mid;
};
/* flags (21bits): 1(shared flag):10(cioff/bidx):10(stack_len) */
#define MRB_ENV_SET_STACK_LEN(e,len) ((e)->flags = (((e)->flags & ~0x3ff)|((unsigned int)(len) & 0x3ff)))
#define MRB_ENV_STACK_LEN(e) ((mrb_int)((e)->flags & 0x3ff))
#define MRB_ENV_STACK_UNSHARED (1<<20)
#define MRB_ENV_UNSHARE_STACK(e) ((e)->flags |= MRB_ENV_STACK_UNSHARED)
#define MRB_ENV_STACK_SHARED_P(e) (((e)->flags & MRB_ENV_STACK_UNSHARED) == 0)
#define MRB_ENV_BIDX(e) (((e)->flags >> 10) & 0x3ff)
#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10))
/* flags (21bits): 1(close):1(touched):1(heap):8(cioff/bidx):8(stack_len) */
#define MRB_ENV_SET_LEN(e,len) ((e)->flags = (((e)->flags & ~0xff)|((unsigned int)(len) & 0xff)))
#define MRB_ENV_LEN(e) ((mrb_int)((e)->flags & 0xff))
#define MRB_ENV_CLOSED (1<<20)
#define MRB_ENV_TOUCHED (1<<19)
#define MRB_ENV_HEAPED (1<<18)
#define MRB_ENV_CLOSE(e) ((e)->flags |= MRB_ENV_CLOSED)
#define MRB_ENV_TOUCH(e) ((e)->flags |= MRB_ENV_TOUCHED)
#define MRB_ENV_HEAP(e) ((e)->flags |= MRB_ENV_HEAPED)
#define MRB_ENV_HEAP_P(e) ((e)->flags & MRB_ENV_HEAPED)
#define MRB_ENV_ONSTACK_P(e) (((e)->flags & MRB_ENV_CLOSED) == 0)
#define MRB_ENV_BIDX(e) (((e)->flags >> 8) & 0xff)
#define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0xff<<8))|((unsigned int)(idx) & 0xff)<<10))
void mrb_env_unshare(mrb_state*, struct REnv*);
+8 -7
View File
@@ -23,9 +23,9 @@ struct RString {
MRB_OBJECT_HEADER;
union {
struct {
mrb_int len;
mrb_ssize len;
union {
mrb_int capa;
mrb_ssize capa;
struct mrb_shared_string *shared;
struct RString *fshared;
} aux;
@@ -54,7 +54,7 @@ struct RStringEmbed {
RSTR_SET_EMBED_LEN((s),(n));\
}\
else {\
(s)->as.heap.len = (mrb_int)(n);\
(s)->as.heap.len = (mrb_ssize)(n);\
}\
} while (0)
#define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary)
@@ -115,8 +115,8 @@ MRB_API mrb_int mrb_str_strlen(mrb_state*, struct RString*);
#define MRB_STR_POOL 16 /* status flags from here */
#define MRB_STR_ASCII 32
#define MRB_STR_EMBED_LEN_SHIFT 6
#define MRB_STR_EMBED_LEN_BITSIZE 5
#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BITSIZE) - 1) << MRB_STR_EMBED_LEN_SHIFT)
#define MRB_STR_EMBED_LEN_BIT 5
#define MRB_STR_EMBED_LEN_MASK (((1 << MRB_STR_EMBED_LEN_BIT) - 1) << MRB_STR_EMBED_LEN_SHIFT)
#define MRB_STR_TYPE_MASK (MRB_STR_POOL - 1)
@@ -447,7 +447,7 @@ MRB_API int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
*/
MRB_API char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_pool(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_pool(mrb_state *mrb, const char *s, mrb_int len, mrb_bool nofree);
uint32_t mrb_str_hash(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
@@ -465,7 +465,8 @@ mrb_bool mrb_str_beg_len(mrb_int str_len, mrb_int *begp, mrb_int *lenp);
mrb_value mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len);
#ifdef MRB_UTF8_STRING
mrb_int mrb_utf8_len(const char *str, mrb_int byte_len);
mrb_int mrb_utf8len(const char *str, const char *end);
mrb_int mrb_utf8_strlen(const char *str, mrb_int byte_len);
#endif
MRB_END_DECL
+41 -44
View File
@@ -34,10 +34,6 @@ typedef uint32_t mrb_sym;
typedef uint8_t mrb_bool;
struct mrb_state;
#if defined(MRB_INT16) && defined(MRB_INT64)
# error "You can't define MRB_INT16 and MRB_INT64 at the same time."
#endif
#if defined _MSC_VER && _MSC_VER < 1800
# define PRIo64 "llo"
# define PRId64 "lld"
@@ -63,14 +59,6 @@ struct mrb_state;
# define MRB_PRIo PRIo64
# define MRB_PRId PRId64
# define MRB_PRIx PRIx64
#elif defined(MRB_INT16)
typedef int16_t mrb_int;
# define MRB_INT_BIT 16
# define MRB_INT_MIN (INT16_MIN>>MRB_FIXNUM_SHIFT)
# define MRB_INT_MAX (INT16_MAX>>MRB_FIXNUM_SHIFT)
# define MRB_PRIo PRIo16
# define MRB_PRId PRId16
# define MRB_PRIx PRIx16
#else
typedef int32_t mrb_int;
# define MRB_INT_BIT 32
@@ -115,32 +103,31 @@ static const unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
#endif
enum mrb_vtype {
MRB_TT_FALSE = 0, /* 0 */
MRB_TT_TRUE, /* 1 */
MRB_TT_FLOAT, /* 2 */
MRB_TT_FIXNUM, /* 3 */
MRB_TT_SYMBOL, /* 4 */
MRB_TT_UNDEF, /* 5 */
MRB_TT_CPTR, /* 6 */
MRB_TT_FREE, /* 7 */
MRB_TT_OBJECT, /* 8 */
MRB_TT_CLASS, /* 9 */
MRB_TT_MODULE, /* 10 */
MRB_TT_ICLASS, /* 11 */
MRB_TT_SCLASS, /* 12 */
MRB_TT_PROC, /* 13 */
MRB_TT_ARRAY, /* 14 */
MRB_TT_HASH, /* 15 */
MRB_TT_STRING, /* 16 */
MRB_TT_RANGE, /* 17 */
MRB_TT_EXCEPTION, /* 18 */
MRB_TT_FILE, /* 19 */
MRB_TT_ENV, /* 20 */
MRB_TT_DATA, /* 21 */
MRB_TT_FIBER, /* 22 */
MRB_TT_ISTRUCT, /* 23 */
MRB_TT_BREAK, /* 24 */
MRB_TT_MAXDEFINE /* 25 */
MRB_TT_FALSE = 0,
MRB_TT_TRUE,
MRB_TT_FLOAT,
MRB_TT_FIXNUM,
MRB_TT_SYMBOL,
MRB_TT_UNDEF,
MRB_TT_CPTR,
MRB_TT_FREE,
MRB_TT_OBJECT,
MRB_TT_CLASS,
MRB_TT_MODULE,
MRB_TT_ICLASS,
MRB_TT_SCLASS,
MRB_TT_PROC,
MRB_TT_ARRAY,
MRB_TT_HASH,
MRB_TT_STRING,
MRB_TT_RANGE,
MRB_TT_EXCEPTION,
MRB_TT_ENV,
MRB_TT_DATA,
MRB_TT_FIBER,
MRB_TT_ISTRUCT,
MRB_TT_BREAK,
MRB_TT_MAXDEFINE
};
#include <mruby/object.h>
@@ -161,6 +148,13 @@ typedef void mrb_value;
#endif
#if defined(MRB_WORD_BOXING) || (defined(MRB_NAN_BOXING) && defined(MRB_64BIT))
struct RCptr {
MRB_OBJECT_HEADER;
void *p;
};
#endif
#if defined(MRB_NAN_BOXING)
#include "boxing_nan.h"
#elif defined(MRB_WORD_BOXING)
@@ -169,9 +163,15 @@ typedef void mrb_value;
#include "boxing_no.h"
#endif
#if !defined(MRB_SYMBOL_BITSIZE)
#define MRB_SYMBOL_BITSIZE (sizeof(mrb_sym) * CHAR_BIT)
#define MRB_SYMBOL_MAX UINT32_MAX
#define MRB_SYMBOL_BIT (sizeof(mrb_sym) * CHAR_BIT - MRB_SYMBOL_SHIFT)
#define MRB_SYMBOL_MAX (UINT32_MAX >> MRB_SYMBOL_SHIFT)
#if INTPTR_MAX < MRB_INT_MAX
typedef intptr_t mrb_ssize;
# define MRB_SSIZE_MAX (INTPTR_MAX>>MRB_FIXNUM_SHIFT)
#else
typedef mrb_int mrb_ssize;
# define MRB_SSIZE_MAX MRB_INT_MAX
#endif
#ifndef mrb_immediate_p
@@ -239,9 +239,6 @@ typedef void mrb_value;
#ifndef mrb_range_p
#define mrb_range_p(o) (mrb_type(o) == MRB_TT_RANGE)
#endif
#ifndef mrb_file_p
#define mrb_file_p(o) (mrb_type(o) == MRB_TT_FILE)
#endif
#ifndef mrb_env_p
#define mrb_env_p(o) (mrb_type(o) == MRB_TT_ENV)
#endif
+4 -4
View File
@@ -47,7 +47,7 @@ MRB_BEGIN_DECL
/*
* Tiny release version number.
*/
#define MRUBY_RELEASE_TEENY 0
#define MRUBY_RELEASE_TEENY 2
/*
* The mruby version.
@@ -62,17 +62,17 @@ MRB_BEGIN_DECL
/*
* Release year.
*/
#define MRUBY_RELEASE_YEAR 2019
#define MRUBY_RELEASE_YEAR 2020
/*
* Release month.
*/
#define MRUBY_RELEASE_MONTH 10
#define MRUBY_RELEASE_MONTH 7
/*
* Release day.
*/
#define MRUBY_RELEASE_DAY 18
#define MRUBY_RELEASE_DAY 10
/*
* Release date as a string.
+1 -20
View File
@@ -20,27 +20,8 @@ class String
end
end
$pp_show = true
if $verbose.nil?
if Rake.respond_to?(:verbose) && !Rake.verbose.nil?
if Rake.verbose.class == TrueClass
# verbose message logging
$pp_show = false
else
$pp_show = true
Rake.verbose(false)
end
else
# could not identify rake version
$pp_show = false
end
else
$pp_show = false if $verbose
end
def _pp(cmd, src, tgt=nil, options={})
return unless $pp_show
return if Rake.verbose
width = 5
template = options[:indent] ? "%#{width*options[:indent]}s %s %s" : "%-#{width}s %s %s"
+5 -33
View File
@@ -173,7 +173,7 @@ module MRuby
obj = objfile(cxx_src) if obj.nil?
file cxx_src => [src, __FILE__] do |t|
FileUtils.mkdir_p File.dirname t.name
mkdir_p File.dirname t.name
IO.write t.name, <<EOS
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS
@@ -276,14 +276,6 @@ EOS
end
end
def cygwin_filename(name)
if name.is_a?(Array)
name.flatten.map { |n| cygwin_filename(n) }
else
`cygpath -w "#{filename(name)}"`.strip
end
end
def exefile(name)
if name.is_a?(Array)
name.flatten.map { |n| exefile(n) }
@@ -320,7 +312,7 @@ EOS
end
def verbose_flag
$verbose ? ' -v' : ''
Rake.verbose ? ' -v' : ''
end
def run_test
@@ -344,7 +336,8 @@ EOS
puts " Binaries: #{@bins.join(', ')}" unless @bins.empty?
unless @gems.empty?
puts " Included Gems:"
@gems.map do |gem|
gems = @gems.sort_by { |gem| gem.name }
gems.each do |gem|
gem_version = " - #{gem.version}" if gem.version != '0.0.0'
gem_summary = " - #{gem.summary}" if gem.summary
puts " #{gem.name}#{gem_version}#{gem_summary}"
@@ -386,7 +379,7 @@ EOS
end
def run_test
@test_runner.runner_options << ' -v' if $verbose
@test_runner.runner_options << verbose_flag
mrbtest = exefile("#{build_dir}/bin/mrbtest")
if (@test_runner.command == nil)
puts "You should run #{mrbtest} on target device."
@@ -395,26 +388,5 @@ EOS
@test_runner.run(mrbtest)
end
end
def big_endian
if @endian
puts "Endian has already specified as #{@endian}."
return
end
@endian = :big
@mrbc.compile_options += ' -E'
compilers.each do |c|
c.defines += %w(MRB_ENDIAN_BIG)
end
end
def little_endian
if @endian
puts "Endian has already specified as #{@endian}."
return
end
@endian = :little
@mrbc.compile_options += ' -e'
end
end # CrossBuild
end # MRuby
+54 -63
View File
@@ -4,7 +4,7 @@ module MRuby
class Command
include Rake::DSL
extend Forwardable
def_delegators :@build, :filename, :objfile, :libfile, :exefile, :cygwin_filename
def_delegators :@build, :filename, :objfile, :libfile, :exefile
attr_accessor :build, :command
def initialize(build)
@@ -24,6 +24,14 @@ module MRuby
target
end
def shellquote(s)
if ENV['OS'] == 'Windows_NT'
"\"#{s}\""
else
"#{s}"
end
end
NotFoundCommands = {}
private
@@ -50,9 +58,9 @@ module MRuby
@source_exts = source_exts
@include_paths = ["#{MRUBY_ROOT}/include"]
@defines = %w()
@option_include_path = '-I%s'
@option_define = '-D%s'
@compile_options = '%{flags} -o %{outfile} -c %{infile}'
@option_include_path = %q[-I"%s"]
@option_define = %q[-D"%s"]
@compile_options = %q[%{flags} -o "%{outfile}" -c "%{infile}"]
@cxx_invalid_flags = []
end
@@ -71,25 +79,16 @@ module MRuby
def all_flags(_defines=[], _include_paths=[], _flags=[])
define_flags = [defines, _defines].flatten.map{ |d| option_define % d }
include_path_flags = [include_paths, _include_paths].flatten.map do |f|
if MRUBY_BUILD_HOST_IS_CYGWIN
option_include_path % cygwin_filename(f)
else
option_include_path % filename(f)
end
option_include_path % filename(f)
end
[flags, define_flags, include_path_flags, _flags].flatten.join(' ')
end
def run(outfile, infile, _defines=[], _include_paths=[], _flags=[])
FileUtils.mkdir_p File.dirname(outfile)
mkdir_p File.dirname(outfile)
_pp "CC", infile.relative_path, outfile.relative_path
if MRUBY_BUILD_HOST_IS_CYGWIN
_run compile_options, { :flags => all_flags(_defines, _include_paths, _flags),
:infile => cygwin_filename(infile), :outfile => cygwin_filename(outfile) }
else
_run compile_options, { :flags => all_flags(_defines, _include_paths, _flags),
:infile => filename(infile), :outfile => filename(outfile) }
end
_run compile_options, { :flags => all_flags(_defines, _include_paths, _flags),
:infile => filename(infile), :outfile => filename(outfile) }
end
def define_rules(build_dir, source_dir='')
@@ -176,18 +175,14 @@ module MRuby
@flags_before_libraries, @flags_after_libraries = [], []
@libraries = []
@library_paths = []
@option_library = '-l%s'
@option_library_path = '-L%s'
@link_options = "%{flags} -o %{outfile} %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}"
@option_library = %q[-l"%s"]
@option_library_path = %q[-L"%s"]
@link_options = %Q[%{flags} -o "%{outfile}" %{objs} %{flags_before_libraries} %{libs} %{flags_after_libraries}]
end
def all_flags(_library_paths=[], _flags=[])
library_path_flags = [library_paths, _library_paths].flatten.map do |f|
if MRUBY_BUILD_HOST_IS_CYGWIN
option_library_path % cygwin_filename(f)
else
option_library_path % filename(f)
end
option_library_path % filename(f)
end
[flags, library_path_flags, _flags].flatten.join(' ')
end
@@ -197,23 +192,15 @@ module MRuby
end
def run(outfile, objfiles, _libraries=[], _library_paths=[], _flags=[], _flags_before_libraries=[], _flags_after_libraries=[])
FileUtils.mkdir_p File.dirname(outfile)
mkdir_p File.dirname(outfile)
library_flags = [libraries, _libraries].flatten.map { |d| option_library % d }
_pp "LD", outfile.relative_path
if MRUBY_BUILD_HOST_IS_CYGWIN
_run link_options, { :flags => all_flags(_library_paths, _flags),
:outfile => cygwin_filename(outfile) , :objs => cygwin_filename(objfiles).join(' '),
:flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
:flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
:libs => library_flags.join(' ') }
else
_run link_options, { :flags => all_flags(_library_paths, _flags),
:outfile => filename(outfile) , :objs => filename(objfiles).join(' '),
:flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
:flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
:libs => library_flags.join(' ') }
end
_run link_options, { :flags => all_flags(_library_paths, _flags),
:outfile => filename(outfile) , :objs => filename(objfiles).map{|f| %Q["#{f}"]}.join(' '),
:flags_before_libraries => [flags_before_libraries, _flags_before_libraries].flatten.join(' '),
:flags_after_libraries => [flags_after_libraries, _flags_after_libraries].flatten.join(' '),
:libs => library_flags.join(' ') }
end
end
@@ -223,17 +210,13 @@ module MRuby
def initialize(build)
super
@command = ENV['AR'] || 'ar'
@archive_options = 'rs %{outfile} %{objs}'
@archive_options = 'rs "%{outfile}" %{objs}'
end
def run(outfile, objfiles)
FileUtils.mkdir_p File.dirname(outfile)
mkdir_p File.dirname(outfile)
_pp "AR", outfile.relative_path
if MRUBY_BUILD_HOST_IS_CYGWIN
_run archive_options, { :outfile => cygwin_filename(outfile), :objs => cygwin_filename(objfiles).join(' ') }
else
_run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).join(' ') }
end
_run archive_options, { :outfile => filename(outfile), :objs => filename(objfiles).map{|f| %Q["#{f}"]}.join(' ') }
end
end
@@ -243,11 +226,11 @@ module MRuby
def initialize(build)
super
@command = 'bison'
@compile_options = '-o %{outfile} %{infile}'
@compile_options = %q[-o "%{outfile}" "%{infile}"]
end
def run(outfile, infile)
FileUtils.mkdir_p File.dirname(outfile)
mkdir_p File.dirname(outfile)
_pp "YACC", infile.relative_path, outfile.relative_path
_run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
end
@@ -259,11 +242,11 @@ module MRuby
def initialize(build)
super
@command = 'gperf'
@compile_options = '-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" %{infile} > %{outfile}'
@compile_options = %q[-L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k"1,3,$" "%{infile}" > "%{outfile}"]
end
def run(outfile, infile)
FileUtils.mkdir_p File.dirname(outfile)
mkdir_p File.dirname(outfile)
_pp "GPERF", infile.relative_path, outfile.relative_path
_run compile_options, { :outfile => filename(outfile) , :infile => filename(infile) }
end
@@ -271,44 +254,50 @@ module MRuby
class Command::Git < Command
attr_accessor :flags
attr_accessor :clone_options, :pull_options, :checkout_options, :reset_options
attr_accessor :clone_options, :pull_options, :checkout_options, :checkout_detach_options, :reset_options
def initialize(build)
super
@command = 'git'
@flags = %w[]
@clone_options = "clone %{flags} %{url} %{dir}"
@pull_options = "--git-dir '%{repo_dir}/.git' --work-tree '%{repo_dir}' pull"
@checkout_options = "--git-dir '%{repo_dir}/.git' --work-tree '%{repo_dir}' checkout %{checksum_hash}"
@reset_options = "--git-dir '%{repo_dir}/.git' --work-tree '%{repo_dir}' reset %{checksum_hash}"
@pull_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} pull"
@checkout_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} checkout %{checksum_hash}"
@checkout_detach_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} checkout --detach %{checksum_hash}"
@reset_options = "--git-dir %{repo_dir}/.git --work-tree %{repo_dir} reset %{checksum_hash}"
end
def run_clone(dir, url, _flags = [])
_pp "GIT", url, dir.relative_path
_run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => url, :dir => filename(dir) }
_run clone_options, { :flags => [flags, _flags].flatten.join(' '), :url => shellquote(url), :dir => shellquote(filename(dir)) }
end
def run_pull(dir, url)
_pp "GIT PULL", url, dir.relative_path
_run pull_options, { :repo_dir => dir }
_run pull_options, { :repo_dir => shellquote(dir) }
end
def run_checkout(dir, checksum_hash)
_pp "GIT CHECKOUT", checksum_hash
_run checkout_options, { :checksum_hash => checksum_hash, :repo_dir => dir }
_pp "GIT CHECKOUT", dir, checksum_hash
_run checkout_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) }
end
def run_checkout_detach(dir, checksum_hash)
_pp "GIT CHECKOUT DETACH", dir, checksum_hash
_run checkout_detach_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) }
end
def run_reset_hard(dir, checksum_hash)
_pp "GIT RESET", checksum_hash
_run reset_options, { :checksum_hash => checksum_hash, :repo_dir => dir }
_pp "GIT RESET", dir, checksum_hash
_run reset_options, { :checksum_hash => checksum_hash, :repo_dir => shellquote(dir) }
end
def commit_hash(dir)
`#{@command} --git-dir '#{dir}/.git' --work-tree '#{dir}' rev-parse --verify HEAD`.strip
`#{@command} --git-dir #{shellquote(dir +'/.git')} --work-tree #{shellquote(dir)} rev-parse --verify HEAD`.strip
end
def current_branch(dir)
`#{@command} --git-dir '#{dir}/.git' --work-tree '#{dir}' rev-parse --abbrev-ref HEAD`.strip
`#{@command} --git-dir #{shellquote(dir + '/.git')} --work-tree #{shellquote(dir)} rev-parse --abbrev-ref HEAD`.strip
end
end
@@ -327,7 +316,9 @@ module MRuby
infiles.each do |f|
_pp "MRBC", f.relative_path, nil, :indent => 2
end
IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}} #{filename(infiles).join(' ')}", 'r+') do |io|
cmd = %Q["#{filename @command}" #{@compile_options % {:funcname => funcname}} #{filename(infiles).map{|f| %Q["#{f}"]}.join(' ')}]
puts cmd if Rake.verbose
IO.popen(cmd, 'r+') do |io|
out.puts io.read
end
# if mrbc execution fail, drop the file
+9 -11
View File
@@ -13,13 +13,12 @@ module MRuby
end
def gem(gemdir, &block)
caller_dir = File.expand_path(File.dirname(/^(.*?):\d/.match(caller.first).to_a[1]))
if gemdir.is_a?(Hash)
gemdir = load_special_path_gem(gemdir)
elsif GemBox.path && gemdir.is_a?(String)
gemdir = File.expand_path(gemdir, File.dirname(GemBox.path))
else
caller_dir = File.expand_path(File.dirname(caller(1,1)[0][/^(.*?):\d/,1]))
gemdir = File.expand_path(gemdir, caller_dir)
end
@@ -58,7 +57,7 @@ module MRuby
if File.exist? mgem_list_dir
git.run_pull mgem_list_dir, mgem_list_url if $pull_gems
else
FileUtils.mkdir_p mgem_list_dir
mkdir_p mgem_list_dir
git.run_clone mgem_list_dir, mgem_list_url, "--depth 1"
end
@@ -87,28 +86,27 @@ module MRuby
if File.exist?(gemdir)
if $pull_gems
git.run_pull gemdir, url
# Jump to the top of the branch
git.run_checkout(gemdir, branch)
git.run_reset_hard gemdir, "origin/#{branch}"
git.run_checkout gemdir, branch
git.run_pull gemdir, url
elsif params[:checksum_hash]
git.run_reset_hard(gemdir, params[:checksum_hash])
git.run_checkout_detach gemdir, params[:checksum_hash]
elsif lock
git.run_reset_hard(gemdir, lock['commit'])
git.run_checkout_detach gemdir, lock['commit']
end
else
options = [params[:options]] || []
options << "--recursive"
options << "--branch \"#{branch}\""
options << "--depth 1" unless params[:checksum_hash]
FileUtils.mkdir_p "#{gem_clone_dir}"
mkdir_p "#{gem_clone_dir}"
git.run_clone gemdir, url, options
# Jump to the specified commit
if params[:checksum_hash]
git.run_reset_hard gemdir, params[:checksum_hash]
git.run_checkout_detach gemdir, params[:checksum_hash]
elsif lock
git.run_reset_hard gemdir, lock['commit']
git.run_checkout_detach gemdir, lock['commit']
end
end
+10 -1
View File
@@ -106,6 +106,15 @@ module MRuby
define_gem_init_builder if @generate_functions
end
def for_windows?
if build.kind_of?(MRuby::CrossBuild)
return %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target)
elsif build.kind_of?(MRuby::Build)
return ('A'..'Z').to_a.any? { |vol| Dir.exist?("#{vol}:") }
end
return false
end
def add_dependency(name, *requirements)
default_gem = requirements.last.kind_of?(Hash) ? requirements.pop : nil
requirements = ['>= 0.0.0'] if requirements.empty?
@@ -157,7 +166,7 @@ module MRuby
def define_gem_init_builder
file objfile("#{build_dir}/gem_init") => [ "#{build_dir}/gem_init.c", File.join(dir, "mrbgem.rake") ]
file "#{build_dir}/gem_init.c" => [build.mrbcfile, __FILE__] + [rbfiles].flatten do |t|
FileUtils.mkdir_p build_dir
mkdir_p build_dir
generate_gem_init("#{build_dir}/gem_init.c")
end
end
+9 -1
View File
@@ -54,6 +54,14 @@ module MRuby
end
end
def shellquote(s)
if ENV['OS'] == 'Windows_NT'
"\"#{s}\""
else
"'#{s}'"
end
end
def mruby
mruby = {
'version' => MRuby::Source::MRUBY_VERSION,
@@ -62,7 +70,7 @@ module MRuby
git_dir = "#{MRUBY_ROOT}/.git"
if File.directory?(git_dir)
mruby['git_commit'] = `git --git-dir '#{git_dir}' --work-tree '#{MRUBY_ROOT}' rev-parse --verify HEAD`.strip
mruby['git_commit'] = `git --git-dir #{shellquote(git_dir)} --work-tree #{shellquote(MRUBY_ROOT)} rev-parse --verify HEAD`.strip
end
mruby
+3 -1
View File
@@ -6,7 +6,9 @@ module MRuby
ROOT = Pathname.new(File.expand_path('../../../',__FILE__))
# Reads a constant defined at version.h
MRUBY_READ_VERSION_CONSTANT = Proc.new { |name| ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?$/)[1] }
MRUBY_READ_VERSION_CONSTANT = Proc.new do |name|
ROOT.join('include','mruby','version.h').read.match(/^#define #{name} +"?([\w\. ]+)"?\r?$/)[1]
end
MRUBY_RUBY_VERSION = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_VERSION']
MRUBY_RUBY_ENGINE = MRUBY_READ_VERSION_CONSTANT['MRUBY_RUBY_ENGINE']
+2 -621
View File
@@ -1,621 +1,2 @@
#!/usr/bin/env ruby
# Original is https://github.com/jimweirich/rake/
# Copyright (c) 2003 Jim Weirich
# License: MIT-LICENSE
require 'getoptlong'
require 'fileutils'
$rake_fiber_table = {}
$rake_jobs = 1
$rake_failed = []
class String
def ext(newext='')
return self.dup if ['.', '..'].include? self
if newext != ''
newext = (newext =~ /^\./) ? newext : ("." + newext)
end
self.chomp(File.extname(self)) << newext
end
def pathmap(spec=nil, &block)
return self if spec.nil?
result = ''
spec.scan(/%\{[^}]*\}-?\d*[sdpfnxX%]|%-?\d+d|%.|[^%]+/) do |frag|
case frag
when '%f'
result << File.basename(self)
when '%n'
result << File.basename(self).ext
when '%d'
result << File.dirname(self)
when '%x'
result << File.extname(self)
when '%X'
result << self.ext
when '%p'
result << self
when '%s'
result << (File::ALT_SEPARATOR || File::SEPARATOR)
when '%-'
# do nothing
when '%%'
result << "%"
when /%(-?\d+)d/
result << pathmap_partial($1.to_i)
when /^%\{([^}]*)\}(\d*[dpfnxX])/
patterns, operator = $1, $2
result << pathmap('%' + operator).pathmap_replace(patterns, &block)
when /^%/
fail ArgumentError, "Unknown pathmap specifier #{frag} in '#{spec}'"
else
result << frag
end
end
result
end
end
module MiniRake
class Task
TASKS = Hash.new
RULES = Array.new
# List of prerequisites for a task.
attr_reader :prerequisites
# Source dependency for rule synthesized tasks. Nil if task was not
# sythesized from a rule.
attr_accessor :source
# Create a task named +task_name+ with no actions or prerequisites..
# use +enhance+ to add actions and prerequisites.
def initialize(task_name)
@name = task_name
@prerequisites = []
@actions = []
end
# Enhance a task with prerequisites or actions. Returns self.
def enhance(deps=nil, &block)
@prerequisites |= deps if deps
@actions << block if block_given?
self
end
# Name of the task.
def name
@name.to_s
end
def done?; @done end
def running?; @running end
# Invoke the task if it is needed. Prerequisites are invoked first.
def invoke
puts "Invoke #{name} (already=[#{@already_invoked}], needed=[#{needed?}])" if $trace
return if @already_invoked
prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
prerequisites.each do |n|
t = Task[n]
unless t.done?
return prerequisites.select{|v| v = Task[v]; v && (!v.done? || !v.running?) }
end
end
@already_invoked = true
if needed?
@running = true
if $rake_root_fiber
return Fiber.new do
self.execute
$rake_root_fiber.transfer
end
else
self.execute
end
end
@done = true
end
# Execute the actions associated with this task.
def execute
puts "Execute #{name}" if $trace
self.class.enhance_with_matching_rule(name) if @actions.empty?
unless $dryrun
@actions.each { |act| act.call(self) }
end
@done = true
@running = false
end
# Is this task needed?
def needed?
true
end
# Timestamp for this task. Basic tasks return the current time for
# their time stamp. Other tasks can be more sophisticated.
def timestamp
Time.now
end
# Class Methods ----------------------------------------------------
class << self
# Clear the task list. This cause rake to immediately forget all
# the tasks that have been assigned. (Normally used in the unit
# tests.)
def clear
TASKS.clear
RULES.clear
end
# List of all defined tasks.
def tasks
TASKS.keys.sort.collect { |tn| Task[tn] }
end
# Return a task with the given name. If the task is not currently
# known, try to synthesize one from the defined rules. If no
# rules are found, but an existing file matches the task name,
# assume it is a file task with no dependencies or actions.
def [](task_name)
task_name = task_name.to_s
if task = TASKS[task_name]
return task
end
if task = enhance_with_matching_rule(task_name)
return task
end
if File.exist?(task_name)
return FileTask.define_task(task_name)
end
fail "Don't know how to rake #{task_name}"
end
# Define a task given +args+ and an option block. If a rule with
# the given name already exists, the prerequisites and actions are
# added to the existing task.
def define_task(args, &block)
task_name, deps = resolve_args(args)
lookup(task_name).enhance([deps].flatten, &block)
end
# Define a rule for synthesizing tasks.
def create_rule(args, &block)
pattern, deps = resolve_args(args)
pattern = Regexp.new(Regexp.quote(pattern) + '$') if String === pattern
RULES << [pattern, deps, block]
end
# Lookup a task. Return an existing task if found, otherwise
# create a task of the current type.
def lookup(task_name)
name = task_name.to_s
TASKS[name] ||= self.new(name)
end
# If a rule can be found that matches the task name, enhance the
# task with the prerequisites and actions from the rule. Set the
# source attribute of the task appropriately for the rule. Return
# the enhanced task or nil of no rule was found.
def enhance_with_matching_rule(task_name, level=0)
fail "Rule Recursion Too Deep: #{task_name}" if level >= 16
RULES.each do |pattern, extensions, block|
next unless pattern && pattern.match(task_name)
sources = extensions.flat_map do |ext|
case ext
when /%/
task_name.pathmap(ext)
when %r{/}
ext
when /^\./
source = task_name.sub(pattern, ext)
source == ext ? task_name.ext(ext) : source
when String
ext
when Proc, Method
ext.arity == 1 ? ext.call(task_name) : ext.call
else
fail "Don't know how to handle rule dependent: #{ext.inspect}"
end
end
prereqs = sources.map do |source|
if File.exist?(source) || TASKS[source]
source
elsif parent = enhance_with_matching_rule(source, level + 1)
parent.name
else
break nil
end
end
if prereqs
task = FileTask.define_task(task_name => prereqs, &block)
task.source = prereqs.first
return task
end
end
nil
end
private
# Resolve the arguments for a task/rule.
def resolve_args(args)
case args
when Hash
fail "Too Many Task Names: #{args.keys.join(' ')}" if args.size > 1
fail "No Task Name Given" if args.size < 1
task_name = args.keys[0]
deps = args[task_name]
deps = [deps] if (String===deps) || (Regexp===deps) || (Proc===deps)
else
task_name = args
deps = []
end
[task_name, deps]
end
end
end
######################################################################
class FileTask < Task
# Is this file task needed? Yes if it doesn't exist, or if its time
# stamp is out of date.
def needed?
return true unless File.exist?(name)
prerequisites = @prerequisites.collect{ |n| n.is_a?(Proc) ? n.call(name) : n }.flatten
latest_prereq = prerequisites.collect{|n| Task[n].timestamp}.max
return false if latest_prereq.nil?
timestamp < latest_prereq
end
# Time stamp for file task.
def timestamp
return Time.at(0) unless File.exist?(name)
stat = File::stat(name.to_s)
stat.directory? ? Time.at(0) : stat.mtime
end
end
module DSL
# Declare a basic task.
def task(args, &block)
MiniRake::Task.define_task(args, &block)
end
# Declare a file task.
def file(args, &block)
MiniRake::FileTask.define_task(args, &block)
end
# Declare a set of files tasks to create the given directories on
# demand.
def directory(args, &block)
MiniRake::FileTask.define_task(args) do |t|
block.call(t) unless block.nil?
dir = args.is_a?(Hash) ? args.keys.first : args
(dir.split(File::SEPARATOR) + ['']).inject do |acc, part|
(acc + File::SEPARATOR).tap do |d|
Dir.mkdir(d) unless File.exists? d
end + part
end
end
end
# Declare a rule for auto-tasks.
def rule(args, &block)
MiniRake::Task.create_rule(args, &block)
end
# Write a message to standard out if $verbose is enabled.
def log(msg)
print " " if $trace && $verbose
puts msg if $verbose
end
# Run the system command +cmd+.
def sh(cmd)
puts cmd if $verbose
if !$rake_root_fiber || Fiber.current == $rake_root_fiber
system(cmd) or fail "Command Failed: [#{cmd}]"
return
end
pid = Process.spawn(cmd)
$rake_fiber_table[pid] = {
fiber: Fiber.current,
command: cmd,
process_waiter: Process.detach(pid)
}
$rake_root_fiber.transfer
end
def desc(text)
end
end
end
Rake = MiniRake
extend MiniRake::DSL
######################################################################
# Task Definition Functions ...
######################################################################
# Rake main application object. When invoking +rake+ from the command
# line, a RakeApp object is created and run.
#
class RakeApp
RAKEFILES = ['rakefile', 'Rakefile']
OPTIONS = [
['--dry-run', '-n', GetoptLong::NO_ARGUMENT,
"Do a dry run without executing actions."],
['--help', '-H', GetoptLong::NO_ARGUMENT,
"Display this help message."],
['--libdir', '-I', GetoptLong::REQUIRED_ARGUMENT,
"Include LIBDIR in the search path for required modules."],
['--nosearch', '-N', GetoptLong::NO_ARGUMENT,
"Do not search parent directories for the Rakefile."],
['--quiet', '-q', GetoptLong::NO_ARGUMENT,
"Do not log messages to standard output (default)."],
['--rakefile', '-f', GetoptLong::REQUIRED_ARGUMENT,
"Use FILE as the rakefile."],
['--require', '-r', GetoptLong::REQUIRED_ARGUMENT,
"Require MODULE before executing rakefile."],
['--tasks', '-T', GetoptLong::NO_ARGUMENT,
"Display the tasks and dependencies, then exit."],
['--pull-gems','-p', GetoptLong::NO_ARGUMENT,
"Pull all git mrbgems."],
['--trace', '-t', GetoptLong::NO_ARGUMENT,
"Turn on invoke/execute tracing."],
['--usage', '-h', GetoptLong::NO_ARGUMENT,
"Display usage."],
['--verbose', '-v', GetoptLong::NO_ARGUMENT,
"Log message to standard output."],
['--directory', '-C', GetoptLong::REQUIRED_ARGUMENT,
"Change executing directory of rakefiles."],
['--jobs', '-j', GetoptLong::REQUIRED_ARGUMENT,
'Execute rake with parallel jobs.']
]
# Create a RakeApp object.
def initialize
@rakefile = nil
@nosearch = false
end
# True if one of the files in RAKEFILES is in the current directory.
# If a match is found, it is copied into @rakefile.
def have_rakefile
RAKEFILES.each do |fn|
if File.exist?(fn)
@rakefile = fn
return true
end
end
return false
end
# Display the program usage line.
def usage
puts "rake [-f rakefile] {options} targets..."
end
# Display the rake command line help.
def help
usage
puts
puts "Options are ..."
puts
OPTIONS.sort.each do |long, short, mode, desc|
if mode == GetoptLong::REQUIRED_ARGUMENT
if desc =~ /\b([A-Z]{2,})\b/
long = long + "=#{$1}"
end
end
printf " %-20s (%s)\n", long, short
printf " %s\n", desc
end
end
# Display the tasks and dependencies.
def display_tasks
MiniRake::Task.tasks.each do |t|
puts "#{t.class} #{t.name}"
t.prerequisites.each { |pre| puts " #{pre}" }
end
end
# Return a list of the command line options supported by the
# program.
def command_line_options
OPTIONS.collect { |lst| lst[0..-2] }
end
# Do the option defined by +opt+ and +value+.
def do_option(opt, value)
case opt
when '--dry-run'
$dryrun = true
$trace = true
when '--help'
help
exit
when '--libdir'
$:.push(value)
when '--nosearch'
@nosearch = true
when '--quiet'
$verbose = false
when '--rakefile'
RAKEFILES.clear
RAKEFILES << value
when '--require'
require value
when '--tasks'
$show_tasks = true
when '--pull-gems'
$pull_gems = true
when '--trace'
$trace = true
when '--usage'
usage
exit
when '--verbose'
$verbose = true
when '--version'
puts "rake, version #{RAKEVERSION}"
exit
when '--directory'
Dir.chdir value
when '--jobs'
$rake_jobs = [value.to_i, 1].max
else
fail "Unknown option: #{opt}"
end
end
# Read and handle the command line options.
def handle_options
$verbose = false
$pull_gems = false
opts = GetoptLong.new(*command_line_options)
opts.each { |opt, value| do_option(opt, value) }
end
# Run the +rake+ application.
def run
handle_options
unless $rake_root_fiber
require 'fiber'
$rake_root_fiber = Fiber.current
end
begin
here = Dir.pwd
while ! have_rakefile
Dir.chdir("..")
if Dir.pwd == here || @nosearch
fail "No Rakefile found (looking for: #{RAKEFILES.join(', ')})"
end
here = Dir.pwd
end
root_tasks = []
ARGV.each do |task_name|
if /^(\w+)=(.*)/.match(task_name)
ENV[$1] = $2
else
root_tasks << task_name
end
end
puts "(in #{Dir.pwd})"
$rakefile = @rakefile
load @rakefile
if $show_tasks
display_tasks
else
root_tasks.push("default") if root_tasks.empty?
# revese tasks for popping
root_tasks.reverse!
tasks = []
until root_tasks.empty?
root_name = root_tasks.pop
tasks << root_name
until tasks.empty?
task_name = tasks.pop
t = MiniRake::Task[task_name]
f = t.invoke
# append additional tasks to task queue
if f.kind_of?(Array)
tasks.push(*f)
tasks.uniq!
end
unless f.kind_of? Fiber
tasks.insert 0, task_name unless t.done?
if root_name == task_name
wait_process
end
next
end
wait_process while $rake_fiber_table.size >= $rake_jobs
f.transfer
end
end
wait_process until $rake_fiber_table.empty?
end
rescue Exception => e
begin
$rake_failed << e
wait_process until $rake_fiber_table.empty?
rescue Exception => next_e
e = next_e
retry
end
end
return if $rake_failed.empty?
puts "rake aborted!"
$rake_failed.each do |ex|
puts ex.message
if $trace || $verbose
puts ex.backtrace.join("\n")
else
puts ex.backtrace.find {|str| str =~ /#{@rakefile}/ } || ""
end
end
exit 1
end
def wait_process(count = 0)
dur = [0.0001 * (10 ** count), 1].min
sleep dur
exited = []
$rake_fiber_table.each do |pid, v|
exited << pid unless v[:process_waiter].alive?
end
exited.each do |pid|
ent = $rake_fiber_table.delete pid
st = ent[:process_waiter].value
# ignore process that isn't created by `sh` method
return if ent.nil?
if st.exitstatus != 0
raise "Command Failed: [#{ent[:command]}]"
end
fail 'task scheduling bug!' if $rake_fiber_table.size >= $rake_jobs
ent[:fiber].transfer
end
wait_process(count + 1) if !$rake_fiber_table.empty? && exited.empty?
end
end
if __FILE__ == $0 then
RakeApp.new.run
end
#! /usr/bin/env ruby
exec "rake", *ARGV
+7
View File
@@ -71,6 +71,10 @@ MRuby::GemBox.new do |conf|
# Use toplevel object (main) methods extension
conf.gem :core => "mruby-toplevel-ext"
# Use Rational/Complex numbers
conf.gem :core => "mruby-rational"
conf.gem :core => "mruby-complex"
# Generate mirb command
conf.gem :core => "mruby-bin-mirb"
@@ -89,6 +93,9 @@ MRuby::GemBox.new do |conf|
# Use Method/UnboundMethod class
conf.gem :core => "mruby-method"
# Use eval()
conf.gem :core => "mruby-eval"
# Use mruby-compiler to build other mrbgems
conf.gem :core => "mruby-compiler"
end
-31
View File
@@ -686,37 +686,6 @@ class Array
satisfied ? low : nil
end
##
# call-seq:
# ary.delete_if { |item| block } -> ary
# ary.delete_if -> Enumerator
#
# Deletes every element of +self+ for which block evaluates to +true+.
#
# The array is changed instantly every time the block is called, not after
# the iteration is over.
#
# See also Array#reject!
#
# If no block is given, an Enumerator is returned instead.
#
# scores = [ 97, 42, 75 ]
# scores.delete_if {|score| score < 80 } #=> [97]
def delete_if(&block)
return to_enum :delete_if unless block
idx = 0
while idx < self.size do
if block.call(self[idx])
self.delete_at(idx)
else
idx += 1
end
end
self
end
##
# call-seq:
# ary.keep_if { |item| block } -> ary
+5 -8
View File
@@ -28,9 +28,8 @@ static mrb_value
mrb_ary_assoc(mrb_state *mrb, mrb_value ary)
{
mrb_int i;
mrb_value v, k;
mrb_get_args(mrb, "o", &k);
mrb_value v;
mrb_value k = mrb_get_arg1(mrb);
for (i = 0; i < RARRAY_LEN(ary); ++i) {
v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
@@ -59,9 +58,8 @@ static mrb_value
mrb_ary_rassoc(mrb_state *mrb, mrb_value ary)
{
mrb_int i;
mrb_value v, value;
mrb_get_args(mrb, "o", &value);
mrb_value v;
mrb_value value = mrb_get_arg1(mrb);
for (i = 0; i < RARRAY_LEN(ary); ++i) {
v = RARRAY_PTR(ary)[i];
@@ -140,9 +138,8 @@ mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
mrb_ary_modify(mrb, a);
if (mrb_get_argc(mrb) == 1) {
mrb_value index;
mrb_value index = mrb_get_arg1(mrb);
mrb_get_args(mrb, "o|i", &index, &len);
switch (mrb_type(index)) {
case MRB_TT_RANGE:
if (mrb_range_beg_len(mrb, index, &i, &len, ARY_LEN(a), TRUE) == MRB_RANGE_OK) {
-19
View File
@@ -195,12 +195,6 @@ assert("Array#reverse_each") do
b << i
end
assert_equal [ "d", "c", "b", "a" ], b
if Object.const_defined?(:Enumerator)
assert_equal [ "d", "c", "b", "a" ], a.reverse_each.to_a
else
true
end
end
assert("Array#rotate") do
@@ -305,19 +299,6 @@ end
#assert("Array#bsearch_index") do
#end
assert("Array#delete_if") do
a = [1, 2, 3, 4, 5]
assert_equal [1, 2, 3, 4, 5], a.delete_if { false }
assert_equal [1, 2, 3, 4, 5], a
a = [1, 2, 3, 4, 5]
assert_equal [], a.delete_if { true }
assert_equal [], a
a = [ 1, 2, 3, 4, 5 ]
assert_equal [1, 2, 3], a.delete_if { |val| val > 3 }
end
assert("Array#keep_if") do
a = [1, 2, 3, 4, 5]
assert_equal [1, 2, 3, 4, 5], a.keep_if { true }
+6 -3
View File
@@ -5,19 +5,22 @@ unless MRuby::Build.current.kind_of?(MRuby::CrossBuild)
spec.author = 'mruby developers'
spec.summary = "#{name} command"
mruby_config_dir = "#{build.build_dir}/bin"
mruby_config = name + (ENV['OS'] == 'Windows_NT' ? '.bat' : '')
mruby_config_path = "#{build.build_dir}/bin/#{mruby_config}"
mruby_config_path = "#{mruby_config_dir}/#{mruby_config}"
make_cfg = "#{build.build_dir}/lib/libmruby.flags.mak"
tmplt_path = "#{__dir__}/#{mruby_config}"
build.bins << mruby_config
file mruby_config_path => [make_cfg, tmplt_path] do |t|
directory mruby_config_dir
file mruby_config_path => [mruby_config_dir, make_cfg, tmplt_path] do |t|
config = Hash[File.readlines(make_cfg).map!(&:chomp).map! {|l|
l.gsub('\\"', '"').split(' = ', 2).map! {|s| s.sub(/^(?=.)/, 'echo ')}
}]
tmplt = File.read(tmplt_path)
File.write(t.name, tmplt.gsub(/(#{Regexp.union(*config.keys)})\b/, config))
FileUtils.chmod(0755, t.name)
chmod(0755, t.name)
end
end
end
+19 -17
View File
@@ -1,9 +1,10 @@
require 'open3'
require 'tempfile'
require 'strscan'
class BinTest_MrubyBinDebugger
@debug1=false
@debug2=true
# @debug1=false
# @debug2=true
def self.test(rubysource, testcase)
script, bin = Tempfile.new(['test', '.rb']), Tempfile.new(['test', '.mrb'])
@@ -19,10 +20,20 @@ class BinTest_MrubyBinDebugger
stdin_data = testcase.map{|t| t[:cmd]}.join("\n") << "\n"
prompt = /^\(#{Regexp.escape(script.path)}:\d+\) /
["bin/mrdb #{script.path}","bin/mrdb -b #{bin.path}"].each do |cmd|
o, s = Open3.capture2(cmd, :stdin_data => stdin_data)
scanner = StringScanner.new(o)
scanner.skip_until(prompt)
testcase.each do |tc|
exp = tc[:exp]
if exp
act = scanner.scan_until(/\n/)
break unless assert_operator act, :start_with?, exp
end
scanner.skip_until(prompt)
end
exp_vals = testcase.map{|t| t.fetch(:exp, nil)}
=begin
if @debug1
o.split("\n").each_with_index do |i,actual|
@@ -41,14 +52,6 @@ end
assert_true actual.include?(exp) unless exp.nil?
end
=end
idx = 0
exp_vals.each do |exp|
next if exp.nil?
idx = o.index(exp, idx)
assert_false idx.nil?
break unless idx
idx += 1
end
end
end
end
@@ -90,8 +93,8 @@ assert('mruby-bin-debugger(print) error') do
# test case
tc = []
tc << {:cmd=>"p (1+2", :exp=>'$1 = SyntaxError'}
tc << {:cmd=>"p bar", :exp=>'$2 = (eval):2: undefined method'}
tc << {:cmd=>"p (1+2", :exp=>'$1 = line 1: syntax error'}
tc << {:cmd=>"p bar", :exp=>'$2 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
@@ -588,7 +591,7 @@ SRC
tc << {:cmd=>'p foo=[foo,bar,baz]', :exp=>'$2 = ["foo", "bar", "baz"]'}
tc << {:cmd=>'p undefined=-1', :exp=>'$3 = -1'}
tc << {:cmd=>'p "#{undefined}"', :exp=>'$4 = (eval):2: undefined method'}
tc << {:cmd=>'p "#{undefined}"', :exp=>'$4 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
@@ -626,7 +629,7 @@ SRC
tc << {:cmd=>'p [a,b]', :exp=>'$13 = [20, 10]'}
tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'}
tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = (eval):2: undefined method'}
tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
@@ -694,8 +697,7 @@ SRC
tc << {:cmd=>'p [a,b]', :exp=>'$13 = [20, 10]'}
tc << {:cmd=>'p undefined=-1', :exp=>'$14 = -1'}
tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = (eval):2: undefined method'}
tc << {:cmd=>'p "#{undefined}"', :exp=>'$15 = undefined method'}
BinTest_MrubyBinDebugger.test(src, tc)
end
@@ -5,7 +5,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <mruby.h>
@@ -7,7 +7,11 @@
#define MRDBCONF_H
#ifndef MRB_ENABLE_DEBUG_HOOK
# error Need 'MRB_ENABLE_DEBUG_HOOK' configuration in your 'build_config.rb'
# error mruby-bin-debugger need 'MRB_ENABLE_DEBUG_HOOK' configuration in your 'build_config.rb'
#endif
#ifdef MRB_DISABLE_STDIO
# error mruby-bin-debugger conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
#endif
/* configuration options: */
+7 -3
View File
@@ -7,6 +7,11 @@
*/
#include <mruby.h>
#ifdef MRB_DISABLE_STDIO
# error mruby-bin-mirb conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
#endif
#include <mruby/array.h>
#include <mruby/proc.h>
#include <mruby/compile.h>
@@ -17,7 +22,6 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
@@ -645,8 +649,8 @@ main(int argc, char **argv)
/* adjust stack length of toplevel environment */
if (mrb->c->cibase->env) {
struct REnv *e = mrb->c->cibase->env;
if (e && MRB_ENV_STACK_LEN(e) < proc->body.irep->nlocals) {
MRB_ENV_SET_STACK_LEN(e, proc->body.irep->nlocals);
if (e && MRB_ENV_LEN(e) < proc->body.irep->nlocals) {
MRB_ENV_SET_LEN(e, proc->body.irep->nlocals);
}
}
/* pass a proc for evaluation */
+26 -23
View File
@@ -1,7 +1,11 @@
#include <stdio.h>
#include <mruby.h>
#ifdef MRB_DISABLE_STDIO
# error mruby-bin-mrbc conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
#endif
#include <stdlib.h>
#include <string.h>
#include <mruby.h>
#include <mruby/compile.h>
#include <mruby/dump.h>
#include <mruby/proc.h>
@@ -32,8 +36,6 @@ usage(const char *name)
"-v print version number, then turn on verbose mode",
"-g produce debugging information",
"-B<symbol> binary <symbol> output in C language format",
"-e generate little endian iseq data",
"-E generate big endian iseq data",
"--remove-lv remove local variables",
"--verbose run at verbose mode",
"--version print the version",
@@ -50,19 +52,26 @@ usage(const char *name)
static char *
get_outfilename(mrb_state *mrb, char *infile, const char *ext)
{
size_t infilelen;
size_t extlen;
size_t ilen, flen, elen;
char *outfile;
char *p;
char *p = NULL;
infilelen = strlen(infile);
extlen = strlen(ext);
outfile = (char*)mrb_malloc(mrb, infilelen + extlen + 1);
memcpy(outfile, infile, infilelen + 1);
ilen = strlen(infile);
flen = ilen;
if (*ext) {
if ((p = strrchr(outfile, '.')) == NULL)
p = outfile + infilelen;
memcpy(p, ext, extlen + 1);
elen = strlen(ext);
if ((p = strrchr(infile, '.'))) {
ilen = p - infile;
}
flen += elen;
}
else {
flen = ilen;
}
outfile = (char*)mrb_malloc(mrb, flen+1);
strncpy(outfile, infile, ilen+1);
if (p) {
strncpy(outfile+ilen, ext, elen+1);
}
return outfile;
@@ -120,10 +129,8 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
args->flags |= DUMP_DEBUG_INFO;
break;
case 'E':
args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK);
break;
case 'e':
args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK);
fprintf(stderr, "%s: -e/-E option no longer needed.\n", args->prog);
break;
case 'h':
return -1;
@@ -156,10 +163,6 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args)
break;
}
}
if (args->verbose && args->initname && (args->flags & DUMP_ENDIAN_MASK) == 0) {
fprintf(stderr, "%s: generating %s endian C file. specify -e/-E for cross compiling.\n",
args->prog, bigendian_p() ? "big" : "little");
}
return i;
}
@@ -183,7 +186,7 @@ partial_hook(struct mrb_parser_state *p)
return -1;
}
fn = args->argv[args->idx++];
p->f = fopen(fn, "r");
p->f = fopen(fn, "rb");
if (p->f == NULL) {
fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, fn);
return -1;
@@ -210,7 +213,7 @@ load_file(mrb_state *mrb, struct mrbc_args *args)
}
else {
need_close = TRUE;
if ((infile = fopen(input, "r")) == NULL) {
if ((infile = fopen(input, "rb")) == NULL) {
fprintf(stderr, "%s: cannot open program file. (%s)\n", args->prog, input);
return mrb_nil_value();
}
+21 -4
View File
@@ -39,6 +39,11 @@ assert '$0 value' do
assert_equal '"-e"', `#{cmd('mruby')} -e #{shellquote('p $0')}`.chomp
end
assert 'ARGV value' do
assert_mruby(%{["ab", "cde"]\n}, "", true, %w[-e p(ARGV) ab cde])
assert_mruby("[]\n", "", true, %w[-e p(ARGV)])
end
assert('float literal') do
script, bin = Tempfile.new('test.rb'), Tempfile.new('test.mrb')
File.write script.path, 'p [3.21, 2e308.infinite?, -2e308.infinite?]'
@@ -80,10 +85,8 @@ assert('mruby -c option') do
end
assert('mruby -d option') do
o = `#{cmd('mruby')} -e #{shellquote('p $DEBUG')}`
assert_equal "false\n", o
o = `#{cmd('mruby')} -d -e #{shellquote('p $DEBUG')}`
assert_equal "true\n", o
assert_mruby("false\n", "", true, ["-e", "p $DEBUG"])
assert_mruby("true\n", "", true, ["-dep $DEBUG"])
end
assert('mruby -e option (no code specified)') do
@@ -125,6 +128,20 @@ assert('mruby -r option (file not found)') do
assert_mruby("", /\A.*: Cannot open library file: .*\n\z/, false, %w[-r _no_exists_])
end
assert('mruby -v option') do
ver_re = '\Amruby \d+\.\d+\.\d+ \(\d+-\d+-\d+\)\n'
assert_mruby(/#{ver_re}\z/, "", true, %w[-v])
assert_mruby(/#{ver_re}^[^\n]*NODE.*\n:end\n\z/m, "", true, %w[-v -e p(:end)])
end
assert('mruby --verbose option') do
assert_mruby(/\A[^\n]*NODE.*\n:end\n\z/m, "", true, %w[--verbose -e p(:end)])
end
assert('mruby --') do
assert_mruby(%{["-x", "1"]\n}, "", true, %w[-e p(ARGV) -- -x 1])
end
assert('mruby invalid short option') do
assert_mruby("", /\A.*: invalid option -1 .*\n\z/, false, %w[-1])
end
-1
View File
@@ -4,7 +4,6 @@ MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec|
spec.summary = 'mruby command'
spec.bins = %w(mruby)
spec.add_dependency('mruby-compiler', :core => 'mruby-compiler')
spec.add_dependency('mruby-error', :core => 'mruby-error')
spec.add_test_dependency('mruby-print', :core => 'mruby-print')
if build.cxx_exception_enabled?
+131 -70
View File
@@ -1,7 +1,11 @@
#include <stdio.h>
#include <mruby.h>
#ifdef MRB_DISABLE_STDIO
# error mruby-bin-mruby conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
#endif
#include <stdlib.h>
#include <string.h>
#include <mruby.h>
#include <mruby/array.h>
#include <mruby/compile.h>
#include <mruby/dump.h>
@@ -9,18 +13,27 @@
struct _args {
FILE *rfp;
char* cmdline;
char *cmdline;
mrb_bool fname : 1;
mrb_bool mrbfile : 1;
mrb_bool check_syntax : 1;
mrb_bool verbose : 1;
mrb_bool version : 1;
mrb_bool debug : 1;
int argc;
char** argv;
char **argv;
int libc;
char **libv;
};
struct options {
int argc;
char **argv;
char *program;
char *opt;
char short_opt[2];
};
static void
usage(const char *name)
{
@@ -44,6 +57,64 @@ usage(const char *name)
printf(" %s\n", *p++);
}
static void
options_init(struct options *opts, int argc, char **argv)
{
opts->argc = argc;
opts->argv = argv;
opts->program = *argv;
*opts->short_opt = 0;
}
static const char *
options_opt(struct options *opts)
{
/* concatenated short options (e.g. `-cv`) */
if (*opts->short_opt && *++opts->opt) {
short_opt:
opts->short_opt[0] = *opts->opt;
opts->short_opt[1] = 0;
return opts->short_opt;
}
while (++opts->argv, --opts->argc) {
opts->opt = *opts->argv;
/* empty || not start with `-` || `-` */
if (!opts->opt[0] || opts->opt[0] != '-' || !opts->opt[1]) return NULL;
if (opts->opt[1] == '-') {
/* `--` */
if (!opts->opt[2]) {
++opts->argv, --opts->argc;
return NULL;
}
/* long option */
opts->opt += 2;
*opts->short_opt = 0;
return opts->opt;
}
else {
/* short option */
++opts->opt;
goto short_opt;
}
}
return NULL;
}
static const char *
options_arg(struct options *opts)
{
if (*opts->short_opt && opts->opt[1]) {
/* concatenated short option and option argument (e.g. `-rLIBRARY`) */
*opts->short_opt = 0;
return opts->opt + 1;
}
--opts->argc, ++opts->argv;
return opts->argc ? *opts->argv : NULL;
}
static char *
dup_arg_item(mrb_state *mrb, const char *item)
{
@@ -56,40 +127,24 @@ dup_arg_item(mrb_state *mrb, const char *item)
static int
parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
{
char **origargv = argv;
static const struct _args args_zero = { 0 };
struct options opts[1];
const char *opt, *item;
*args = args_zero;
for (argc--,argv++; argc > 0; argc--,argv++) {
char *item;
if (argv[0][0] != '-') break;
if (strlen(*argv) <= 1) {
argc--; argv++;
args->rfp = stdin;
break;
}
item = argv[0] + 1;
switch (*item++) {
case 'b':
options_init(opts, argc, argv);
while ((opt = options_opt(opts))) {
if (strcmp(opt, "b") == 0) {
args->mrbfile = TRUE;
break;
case 'c':
}
else if (strcmp(opt, "c") == 0) {
args->check_syntax = TRUE;
break;
case 'd':
}
else if (strcmp(opt, "d") == 0) {
args->debug = TRUE;
break;
case 'e':
if (item[0]) {
goto append_cmdline;
}
else if (argc > 1) {
argc--; argv++;
item = argv[0];
append_cmdline:
}
else if (strcmp(opt, "e") == 0) {
if ((item = options_arg(opts))) {
if (!args->cmdline) {
args->cmdline = dup_arg_item(mrb, item);
}
@@ -106,59 +161,65 @@ append_cmdline:
}
}
else {
fprintf(stderr, "%s: No code specified for -e\n", *origargv);
fprintf(stderr, "%s: No code specified for -e\n", opts->program);
return EXIT_FAILURE;
}
break;
case 'h':
usage(*origargv);
}
else if (strcmp(opt, "h") == 0) {
usage(opts->program);
exit(EXIT_SUCCESS);
case 'r':
if (!item[0]) {
if (argc <= 1) {
fprintf(stderr, "%s: No library specified for -r\n", *origargv);
return EXIT_FAILURE;
}
else if (strcmp(opt, "r") == 0) {
if ((item = options_arg(opts))) {
if (args->libc == 0) {
args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
}
argc--; argv++;
item = argv[0];
}
if (args->libc == 0) {
args->libv = (char**)mrb_malloc(mrb, sizeof(char*));
else {
args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
}
args->libv[args->libc++] = dup_arg_item(mrb, item);
}
else {
args->libv = (char**)mrb_realloc(mrb, args->libv, sizeof(char*) * (args->libc + 1));
fprintf(stderr, "%s: No library specified for -r\n", opts->program);
return EXIT_FAILURE;
}
args->libv[args->libc++] = dup_arg_item(mrb, item);
break;
case 'v':
if (!args->verbose) mrb_show_version(mrb);
args->verbose = TRUE;
break;
case '-':
if (strcmp((*argv) + 2, "version") == 0) {
}
else if (strcmp(opt, "v") == 0) {
if (!args->verbose) {
mrb_show_version(mrb);
exit(EXIT_SUCCESS);
args->version = TRUE;
}
else if (strcmp((*argv) + 2, "verbose") == 0) {
args->verbose = TRUE;
break;
}
else if (strcmp((*argv) + 2, "copyright") == 0) {
mrb_show_copyright(mrb);
exit(EXIT_SUCCESS);
}
default:
fprintf(stderr, "%s: invalid option %s (-h will show valid options)\n", *origargv, *argv);
args->verbose = TRUE;
}
else if (strcmp(opt, "version") == 0) {
mrb_show_version(mrb);
exit(EXIT_SUCCESS);
}
else if (strcmp(opt, "verbose") == 0) {
args->verbose = TRUE;
}
else if (strcmp(opt, "copyright") == 0) {
mrb_show_copyright(mrb);
exit(EXIT_SUCCESS);
}
else {
fprintf(stderr, "%s: invalid option %s%s (-h will show valid options)\n",
opts->program, opt[1] ? "--" : "-", opt);
return EXIT_FAILURE;
}
}
if (args->rfp == NULL && args->cmdline == NULL) {
if (*argv == NULL) args->rfp = stdin;
argc = opts->argc; argv = opts->argv;
if (args->cmdline == NULL) {
if (*argv == NULL) {
if (args->version) exit(EXIT_SUCCESS);
args->rfp = stdin;
}
else {
args->rfp = fopen(argv[0], args->mrbfile ? "rb" : "r");
args->rfp = strcmp(argv[0], "-") == 0 ?
stdin : fopen(argv[0], args->mrbfile ? "rb" : "r");
if (args->rfp == NULL) {
fprintf(stderr, "%s: Cannot open program file: %s\n", *origargv, *argv);
fprintf(stderr, "%s: Cannot open program file: %s\n", opts->program, argv[0]);
return EXIT_FAILURE;
}
args->fname = TRUE;
@@ -1,7 +1,11 @@
#include <stdio.h>
#include <mruby.h>
#ifdef MRB_DISABLE_STDIO
# error mruby-bin-strip conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
#endif
#include <stdlib.h>
#include <string.h>
#include <mruby.h>
#include <mruby/irep.h>
#include <mruby/dump.h>
+11 -2
View File
@@ -5,7 +5,11 @@
static mrb_value
mrb_mod_name(mrb_state *mrb, mrb_value self)
{
return mrb_class_path(mrb, mrb_class_ptr(self));
mrb_value name = mrb_class_path(mrb, mrb_class_ptr(self));
if (mrb_string_p(name)) {
MRB_SET_FROZEN_FLAG(mrb_basic_ptr(name));
}
return name;
}
static mrb_value
@@ -39,10 +43,15 @@ mrb_mod_module_exec(mrb_state *mrb, mrb_value self)
const mrb_value *argv;
mrb_int argc;
mrb_value blk;
struct RClass *c;
mrb_get_args(mrb, "*&!", &argv, &argc, &blk);
mrb->c->ci->target_class = mrb_class_ptr(self);
c = mrb_class_ptr(self);
if (mrb->c->ci->acc < 0) {
return mrb_yield_with_class(mrb, blk, argc, argv, self, c);
}
mrb->c->ci->target_class = c;
return mrb_yield_cont(mrb, blk, self, argc, argv);
}
+92 -49
View File
@@ -281,15 +281,6 @@ no_optimize(codegen_scope *s)
return FALSE;
}
static
mrb_bool
on_eval(codegen_scope *s)
{
if (s && s->parser && s->parser->on_eval)
return TRUE;
return FALSE;
}
struct mrb_insn_data
mrb_decode_insn(const mrb_code *pc)
{
@@ -407,9 +398,6 @@ gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep)
if (no_peephole(s)) {
normal:
genop_2(s, OP_MOVE, dst, src);
if (on_eval(s)) {
genop_0(s, OP_NOP);
}
return;
}
else {
@@ -599,7 +587,7 @@ new_lit(codegen_scope *s, mrb_value val)
switch (mrb_type(val)) {
case MRB_TT_STRING:
*pv = mrb_str_pool(s->mrb, val);
*pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val)));
break;
#ifndef MRB_WITHOUT_FLOAT
@@ -674,6 +662,43 @@ lv_idx(codegen_scope *s, mrb_sym id)
return 0;
}
static int
search_upvar(codegen_scope *s, mrb_sym id, int *idx)
{
struct RProc *u;
int lv = 0;
codegen_scope *up = s->prev;
while (up) {
*idx = lv_idx(up, id);
if (*idx > 0) {
return lv;
}
lv ++;
up = up->prev;
}
if (lv < 1) lv = 1;
u = s->parser->upper;
while (u && !MRB_PROC_CFUNC_P(u)) {
struct mrb_irep *ir = u->body.irep;
uint_fast16_t n = ir->nlocals;
const struct mrb_locals *v = ir->lv;
for (; n > 1; n --, v ++) {
if (v->name == id) {
*idx = v->r;
return lv - 1;
}
}
if (MRB_PROC_SCOPE_P(u)) break;
u = u->upper;
lv ++;
}
codegen_error(s, "Can't found local variables");
return -1; /* not reached */
}
static void
for_body(codegen_scope *s, node *tree)
{
@@ -771,7 +796,7 @@ lambda_body(codegen_scope *s, node *tree, int blk)
s->ainfo = (((ma+oa) & 0x3f) << 7) /* (12bits = 5:1:5:1) */
| ((ra & 0x1) << 6)
| ((pa & 0x1f) << 1)
| (kd & 0x1);
| ((ka | kd) != 0 ? 0x01 : 0x00);
genop_W(s, OP_ENTER, a);
/* generate jump table for optional arguments initializer */
pos = new_label(s);
@@ -786,12 +811,19 @@ lambda_body(codegen_scope *s, node *tree, int blk)
i = 0;
while (opt) {
int idx;
mrb_sym id = nsym(opt->car->car);
dispatch(s, pos+i*3+1);
codegen(s, opt->car->cdr, VAL);
pop();
idx = lv_idx(s, nsym(opt->car->car));
gen_move(s, idx, cursp(), 0);
idx = lv_idx(s, id);
if (idx > 0) {
gen_move(s, idx, cursp(), 0);
}
else {
int lv = search_upvar(s, id, &idx);
genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
}
i++;
opt = opt->cdr;
}
@@ -818,11 +850,19 @@ lambda_body(codegen_scope *s, node *tree, int blk)
mrb_assert(nint(kwd->car) == NODE_KW_ARG);
if (def_arg) {
int idx;
genop_2(s, OP_KEY_P, lv_idx(s, kwd_sym), new_sym(s, kwd_sym));
jmpif_key_p = genjmp2(s, OP_JMPIF, lv_idx(s, kwd_sym), 0, 0);
codegen(s, def_arg, VAL);
pop();
gen_move(s, lv_idx(s, kwd_sym), cursp(), 0);
idx = lv_idx(s, kwd_sym);
if (idx > 0) {
gen_move(s, idx, cursp(), 0);
}
else {
int lv = search_upvar(s, kwd_sym, &idx);
genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
}
jmp_def_set = genjmp(s, OP_JMP, 0);
dispatch(s, jmpif_key_p);
}
@@ -1103,25 +1143,18 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val)
if (idx > 0) {
if (idx != sp) {
gen_move(s, idx, sp, val);
if (val && on_eval(s)) genop_0(s, OP_NOP);
}
break;
}
else { /* upvar */
int lv = 0;
codegen_scope *up = s->prev;
while (up) {
idx = lv_idx(up, nsym(tree));
if (idx > 0) {
genop_3(s, OP_SETUPVAR, sp, idx, lv);
break;
}
lv++;
up = up->prev;
}
int lv = search_upvar(s, nsym(tree), &idx);
genop_3(s, OP_SETUPVAR, sp, idx, lv);
}
break;
case NODE_NVAR:
idx = nint(tree);
codegen_error(s, "Can't assign to numbered parameter");
break;
case NODE_IVAR:
idx = new_sym(s, nsym(tree));
genop_2(s, OP_SETIV, sp, idx);
@@ -1856,7 +1889,7 @@ codegen(codegen_scope *s, node *tree, int val)
len++;
}
tree = tree->cdr;
if (val && len == 255) {
if (val && cursp() > 127) {
pop_n(len*2);
if (!update) {
genop_2(s, OP_HASH, cursp(), len);
@@ -2320,26 +2353,25 @@ codegen(codegen_scope *s, node *tree, int val)
if (idx > 0) {
gen_move(s, cursp(), idx, val);
if (val && on_eval(s)) genop_0(s, OP_NOP);
}
else {
int lv = 0;
codegen_scope *up = s->prev;
while (up) {
idx = lv_idx(up, nsym(tree));
if (idx > 0) {
genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
break;
}
lv++;
up = up->prev;
}
int lv = search_upvar(s, nsym(tree), &idx);
genop_3(s, OP_GETUPVAR, cursp(), idx, lv);
}
push();
}
break;
case NODE_NVAR:
if (val) {
int idx = nint(tree);
gen_move(s, cursp(), idx, val);
push();
}
break;
case NODE_GVAR:
{
int sym = new_sym(s, nsym(tree));
@@ -2425,12 +2457,20 @@ codegen(codegen_scope *s, node *tree, int val)
else
#endif
{
if (i == -1) genop_1(s, OP_LOADI__1, cursp());
else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
if (i < 0) {
if (i == -1) genop_1(s, OP_LOADI__1, cursp());
else if (i >= -0xff) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
else if (i >= -0x8000) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
else goto lit_int;
}
else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp());
else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i);
else if (i <= 0xff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i);
else if (i <= 0x7fff) genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
else {
int off = new_lit(s, mrb_fixnum_value(i));
int off;
lit_int:
off = new_lit(s, mrb_fixnum_value(i));
genop_2(s, OP_LOADL, cursp(), off);
}
}
@@ -2486,9 +2526,12 @@ codegen(codegen_scope *s, node *tree, int val)
else {
#endif
if (i == -1) genop_1(s, OP_LOADI__1, cursp());
else if (i >= -0xffff) {
else if (i >= -0xff) {
genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i);
}
else if (i >= -0x8000) {
genop_2S(s, OP_LOADI16, cursp(), (uint16_t)i);
}
else {
int off = new_lit(s, mrb_fixnum_value(i));
genop_2(s, OP_LOADL, cursp(), off);
+1
View File
@@ -51,6 +51,7 @@ enum node_type {
NODE_IVAR,
NODE_CONST,
NODE_CVAR,
NODE_NVAR,
NODE_NTH_REF,
NODE_BACK_REF,
NODE_MATCH,
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+13 -15
View File
@@ -3,35 +3,33 @@ MRuby::Gem::Specification.new 'mruby-compiler' do |spec|
spec.author = 'mruby developers'
spec.summary = 'mruby compiler library'
current_dir = spec.dir
current_build_dir = spec.build_dir
lex_def = "#{current_dir}/core/lex.def"
core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f|
lex_def = "#{dir}/core/lex.def"
core_objs = Dir.glob("#{dir}/core/*.c").map { |f|
next nil if build.cxx_exception_enabled? and f =~ /(codegen).c$/
objfile(f.pathmap("#{current_build_dir}/core/%n"))
objfile(f.pathmap("#{build_dir}/core/%n"))
}.compact
if build.cxx_exception_enabled?
core_objs <<
build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx",
objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) <<
build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx")
build.compile_as_cxx("#{dir}/core/y.tab.c", "#{build_dir}/core/y.tab.cxx",
objfile("#{build_dir}/y.tab"), ["#{dir}/core"]) <<
build.compile_as_cxx("#{dir}/core/codegen.c", "#{build_dir}/core/codegen.cxx")
else
core_objs << objfile("#{current_build_dir}/core/y.tab")
file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t|
cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"]
core_objs << objfile("#{build_dir}/core/y.tab")
file objfile("#{build_dir}/core/y.tab") => "#{dir}/core/y.tab.c" do |t|
cc.run t.name, t.prerequisites.first, [], ["#{dir}/core"]
end
end
# Parser
file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y", lex_def] do |t|
FileUtils.mkdir_p File.dirname t.name
file "#{dir}/core/y.tab.c" => ["#{dir}/core/parse.y", lex_def] do |t|
yacc.run t.name, t.prerequisites.first
content = File.read(t.name).gsub(/^#line +\d+ +"\K.*$/){$&.relative_path}
File.write(t.name, content)
end
# Lexical analyzer
file lex_def => "#{current_dir}/core/keywords" do |t|
file lex_def => "#{dir}/core/keywords" do |t|
gperf.run t.name, t.prerequisites.first
end
-3
View File
@@ -3,8 +3,5 @@ MRuby::Gem::Specification.new('mruby-complex') do |spec|
spec.author = 'mruby developers'
spec.summary = 'Complex class'
spec.add_dependency 'mruby-metaprog', core: 'mruby-metaprog'
spec.add_dependency 'mruby-object-ext', core: 'mruby-object-ext'
spec.add_dependency 'mruby-numeric-ext', core: 'mruby-numeric-ext'
spec.add_dependency 'mruby-math', core: 'mruby-math'
end
+6 -6
View File
@@ -8,7 +8,7 @@ class Complex < Numeric
end
def to_s
"#{real}#{'+' unless imaginary.negative?}#{imaginary}i"
"#{real}#{'+' unless imaginary < 0}#{imaginary}i"
end
def +@
@@ -56,7 +56,7 @@ class Complex < Numeric
if rhs.is_a? Complex
real == rhs.real && imaginary == rhs.imaginary
elsif rhs.is_a? Numeric
imaginary.zero? && real == rhs
imaginary == 0 && real == rhs
end
end
@@ -106,14 +106,14 @@ class Complex < Numeric
[Fixnum, Float].each do |cls|
[:+, :-, :*, :/, :==].each do |op|
cls.instance_exec do
original_operator_name = "__original_operator_#{op}_complex"
cls.instance_eval do
original_operator_name = :"__original_operator_#{op}_complex"
alias_method original_operator_name, op
define_method op do |rhs|
if rhs.is_a? Complex
Complex(self).send(op, rhs)
Complex(self).__send__(op, rhs)
else
send(original_operator_name, rhs)
__send__(original_operator_name, rhs)
end
end
end
+1 -2
View File
@@ -174,7 +174,7 @@ div_pair(struct float_pair *q, struct float_pair const *a,
static mrb_value
complex_div(mrb_state *mrb, mrb_value self)
{
mrb_value rhs;
mrb_value rhs = mrb_get_arg1(mrb);
struct mrb_complex *a, *b;
struct float_pair ar, ai, br, bi;
struct float_pair br2, bi2;
@@ -183,7 +183,6 @@ complex_div(mrb_state *mrb, mrb_value self)
struct float_pair ai_br, ar_bi;
struct float_pair zr, zi;
mrb_get_args(mrb, "o", &rhs);
a = complex_ptr(mrb, self);
b = complex_ptr(mrb, rhs);
+3 -3
View File
@@ -8,7 +8,7 @@ mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state)
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
struct mrb_jmpbuf c_jmp;
mrb_value result = mrb_nil_value();
mrb_int ai = mrb_gc_arena_save(mrb);
int ai = mrb_gc_arena_save(mrb);
if (state) { *state = FALSE; }
@@ -34,7 +34,7 @@ mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure,
struct mrb_jmpbuf *prev_jmp = mrb->jmp;
struct mrb_jmpbuf c_jmp;
mrb_value result;
mrb_int ai = mrb_gc_arena_save(mrb);
int ai = mrb_gc_arena_save(mrb);
MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
@@ -71,7 +71,7 @@ mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_fun
mrb_value result;
mrb_bool error_matched = FALSE;
mrb_int i;
mrb_int ai = mrb_gc_arena_save(mrb);
int ai = mrb_gc_arena_save(mrb);
MRB_TRY(&c_jmp) {
mrb->jmp = &c_jmp;
+4 -215
View File
@@ -9,217 +9,6 @@
mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p);
mrb_value mrb_obj_instance_eval(mrb_state *mrb, mrb_value self);
static struct mrb_irep *
get_closure_irep(mrb_state *mrb, int level)
{
struct RProc *proc = mrb->c->ci[-1].proc;
while (level--) {
if (!proc) return NULL;
proc = proc->upper;
}
if (!proc) return NULL;
if (MRB_PROC_CFUNC_P(proc)) {
return NULL;
}
return proc->body.irep;
}
/* search for irep lev above the bottom */
static mrb_irep*
search_irep(mrb_irep *top, int bnest, int lev, mrb_irep *bottom)
{
int i;
for (i=0; i<top->rlen; i++) {
mrb_irep* tmp = top->reps[i];
if (tmp == bottom) return top;
tmp = search_irep(tmp, bnest-1, lev, bottom);
if (tmp) {
if (bnest == lev) return top;
return tmp;
}
}
return NULL;
}
static uint16_t
search_variable(mrb_state *mrb, mrb_sym vsym, int bnest)
{
mrb_irep *virep;
int level;
int pos;
for (level = 0; (virep = get_closure_irep(mrb, level)); level++) {
if (virep->lv == NULL) {
continue;
}
for (pos = 0; pos < virep->nlocals - 1; pos++) {
if (vsym == virep->lv[pos].name) {
return (pos+1)<<8 | (level+bnest);
}
}
}
return 0;
}
static int
irep_argc(mrb_irep *irep)
{
mrb_code c;
c = irep->iseq[0];
if (c == OP_ENTER) {
mrb_aspec ax = PEEK_W(irep->iseq+1);
/* extra 1 means a slot for block */
return MRB_ASPEC_REQ(ax)+MRB_ASPEC_OPT(ax)+MRB_ASPEC_REST(ax)+MRB_ASPEC_POST(ax)+1;
}
return 0;
}
static mrb_bool
potential_upvar_p(struct mrb_locals *lv, uint16_t v, int argc, uint16_t nlocals)
{
if (v >= nlocals) return FALSE;
/* skip arguments */
if (v < argc+1) return FALSE;
return TRUE;
}
extern uint8_t mrb_insn_size[];
extern uint8_t mrb_insn_size1[];
extern uint8_t mrb_insn_size2[];
extern uint8_t mrb_insn_size3[];
static void
patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top)
{
int i;
uint32_t a;
uint16_t b;
uint8_t c;
mrb_code insn;
int argc = irep_argc(irep);
mrb_code *iseq = (mrb_code *)irep->iseq;
mrb_assert((irep->flags & MRB_ISEQ_NO_FREE) == 0);
for (i = 0; i < irep->ilen; ) {
insn = iseq[i];
switch(insn){
case OP_EPUSH:
b = PEEK_S(iseq+i+1);
patch_irep(mrb, irep->reps[b], bnest + 1, top);
break;
case OP_LAMBDA:
case OP_BLOCK:
a = PEEK_B(iseq+i+1);
b = PEEK_B(iseq+i+2);
patch_irep(mrb, irep->reps[b], bnest + 1, top);
break;
case OP_SEND:
b = PEEK_B(iseq+i+2);
c = PEEK_B(iseq+i+3);
if (c != 0) {
break;
}
else {
uint16_t arg = search_variable(mrb, irep->syms[b], bnest);
if (arg != 0) {
/* must replace */
iseq[i] = OP_GETUPVAR;
iseq[i+2] = arg >> 8;
iseq[i+3] = arg & 0xff;
}
}
break;
case OP_MOVE:
a = PEEK_B(iseq+i+1);
b = PEEK_B(iseq+i+2);
/* src part */
if (potential_upvar_p(irep->lv, b, argc, irep->nlocals)) {
uint16_t arg = search_variable(mrb, irep->lv[b - 1].name, bnest);
if (arg != 0) {
/* must replace */
iseq[i] = insn = OP_GETUPVAR;
iseq[i+2] = arg >> 8;
iseq[i+3] = arg & 0xff;
}
}
/* dst part */
if (potential_upvar_p(irep->lv, a, argc, irep->nlocals)) {
uint16_t arg = search_variable(mrb, irep->lv[a - 1].name, bnest);
if (arg != 0) {
/* must replace */
iseq[i] = insn = OP_SETUPVAR;
iseq[i+1] = (mrb_code)b;
iseq[i+2] = arg >> 8;
iseq[i+3] = arg & 0xff;
}
}
break;
case OP_GETUPVAR:
a = PEEK_B(iseq+i+1);
b = PEEK_B(iseq+i+2);
c = PEEK_B(iseq+i+3);
{
int lev = c+1;
mrb_irep *tmp = search_irep(top, bnest, lev, irep);
if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
if (arg != 0) {
/* must replace */
iseq[i] = OP_GETUPVAR;
iseq[i+2] = arg >> 8;
iseq[i+3] = arg & 0xff;
}
}
}
break;
case OP_SETUPVAR:
a = PEEK_B(iseq+i+1);
b = PEEK_B(iseq+i+2);
c = PEEK_B(iseq+i+3);
{
int lev = c+1;
mrb_irep *tmp = search_irep(top, bnest, lev, irep);
if (potential_upvar_p(tmp->lv, b, irep_argc(tmp), tmp->nlocals)) {
uint16_t arg = search_variable(mrb, tmp->lv[b-1].name, bnest);
if (arg != 0) {
/* must replace */
iseq[i] = OP_SETUPVAR;
iseq[i+1] = a;
iseq[i+2] = arg >> 8;
iseq[i+3] = arg & 0xff;
}
}
}
break;
case OP_EXT1:
insn = PEEK_B(iseq+i+1);
i += mrb_insn_size1[insn]+1;
continue;
case OP_EXT2:
insn = PEEK_B(iseq+i+1);
i += mrb_insn_size2[insn]+1;
continue;
case OP_EXT3:
insn = PEEK_B(iseq+i+1);
i += mrb_insn_size3[insn]+1;
continue;
}
i+=mrb_insn_size[insn];
}
}
void mrb_codedump_all(mrb_state*, struct RProc*);
static struct RProc*
@@ -243,7 +32,8 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
mrbc_filename(mrb, cxt, file ? file : "(eval)");
cxt->capture_errors = TRUE;
cxt->no_optimize = TRUE;
cxt->on_eval = TRUE;
ci = (mrb->c->ci > mrb->c->cibase) ? mrb->c->ci - 1 : mrb->c->cibase;
cxt->upper = ci->proc && MRB_PROC_CFUNC_P(ci->proc) ? NULL : ci->proc;
p = mrb_parse_nstring(mrb, s, len, cxt);
@@ -298,7 +88,7 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
e->mid = ci->mid;
e->stack = ci[1].stackent;
e->cxt = mrb->c;
MRB_ENV_SET_STACK_LEN(e, ci->proc->body.irep->nlocals);
MRB_ENV_SET_LEN(e, ci->proc->body.irep->nlocals);
bidx = ci->argc;
if (ci->argc < 0) bidx = 2;
else bidx += 1;
@@ -311,7 +101,6 @@ create_proc_from_string(mrb_state *mrb, char *s, mrb_int len, mrb_value binding,
}
proc->upper = ci->proc;
mrb->c->ci->target_class = target_class;
patch_irep(mrb, proc->body.irep, 0, proc->body.irep);
/* mrb_codedump_all(mrb, proc); */
mrb_parser_free(p);
@@ -390,7 +179,7 @@ void
mrb_mruby_eval_gem_init(mrb_state* mrb)
{
mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3));
mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2));
mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK());
}
void
+21
View File
@@ -130,3 +130,24 @@ Proc.new { foo }
EOS
}
end
assert('Calling the same method as the variable name') do
hoge = Object.new
def hoge.fuga
"Hit!"
end
assert_equal("Hit!") { fuga = "Miss!"; eval "hoge.fuga" }
assert_equal("Hit!") { fuga = "Miss!"; -> { eval "hoge.fuga" }.call }
assert_equal("Hit!") { -> { fuga = "Miss!"; eval "hoge.fuga" }.call }
assert_equal("Hit!") { fuga = "Miss!"; eval("-> { hoge.fuga }").call }
end
assert('Access numbered parameter from eval') do
hoge = Object.new
def hoge.fuga(a, &b)
b.call(a)
end
assert_equal(6) {
hoge.fuga(3) { _1 + eval("_1") }
}
end
+9 -4
View File
@@ -4,12 +4,17 @@
static mrb_value
f_exit(mrb_state *mrb, mrb_value self)
{
mrb_int i = EXIT_SUCCESS;
mrb_value status = mrb_true_value();
int istatus;
mrb_get_args(mrb, "|o", &status);
istatus = mrb_true_p(status) ? EXIT_SUCCESS :
mrb_false_p(status) ? EXIT_FAILURE :
(int)mrb_int(mrb, status);
exit(istatus);
mrb_get_args(mrb, "|i", &i);
exit((int)i);
/* not reached */
return mrb_nil_value();
return status;
}
void
+2 -3
View File
@@ -291,8 +291,7 @@ mrb_fiber_alive_p(mrb_state *mrb, mrb_value self)
static mrb_value
fiber_eq(mrb_state *mrb, mrb_value self)
{
mrb_value other;
mrb_get_args(mrb, "o", &other);
mrb_value other = mrb_get_arg1(mrb);
if (!mrb_fiber_p(other)) {
return mrb_false_value();
@@ -409,7 +408,7 @@ mrb_mruby_fiber_gem_init(mrb_state* mrb)
c = mrb_define_class(mrb, "Fiber", mrb->object_class);
MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER);
mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE());
mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE()|MRB_ARGS_BLOCK());
mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY());
mrb_define_method(mrb, c, "transfer", fiber_transfer, MRB_ARGS_ANY());
mrb_define_method(mrb, c, "alive?", fiber_alive_p, MRB_ARGS_NONE());
-2
View File
@@ -2,7 +2,5 @@ MRuby::Gem::Specification.new('mruby-hash-ext') do |spec|
spec.license = 'MIT'
spec.author = 'mruby developers'
spec.summary = 'Hash class extension'
spec.add_dependency 'mruby-enum-ext', core: 'mruby-enum-ext'
spec.add_dependency 'mruby-array-ext', core: 'mruby-array-ext'
spec.add_test_dependency 'mruby-enumerator', core: 'mruby-enumerator'
end
+1 -3
View File
@@ -53,10 +53,8 @@ hash_slice(mrb_state *mrb, mrb_value hash)
mrb_int argc, i;
mrb_get_args(mrb, "*", &argv, &argc);
if (argc == 0) {
return mrb_hash_new_capa(mrb, argc);
}
result = mrb_hash_new_capa(mrb, argc);
if (argc == 0) return result; /* empty hash */
for (i = 0; i < argc; i++) {
mrb_value key = argv[i];
mrb_value val;
+3 -7
View File
@@ -269,10 +269,8 @@ assert("Hash#transform_keys") do
h.transform_keys{|k| k+"!"})
assert_equal({1 => 100, 2 => 200},
h.transform_keys{|k|k.to_i})
assert_equal({"1.0" => 100, "2.1" => 200},
h.transform_keys.with_index{|k, i| "#{k}.#{i}"})
assert_equal(h, h.transform_keys!{|k|k.to_i})
assert_equal(h, {1 => 100, 2 => 200})
assert_same(h, h.transform_keys!{|k|k.to_i})
assert_equal({1 => 100, 2 => 200}, h)
end
assert("Hash#transform_values") do
@@ -281,9 +279,7 @@ assert("Hash#transform_values") do
h.transform_values{|v| v * v + 1})
assert_equal({a: "1", b: "2", c: "3"},
h.transform_values{|v|v.to_s})
assert_equal({a: "1.0", b: "2.1", c: "3.2"},
h.transform_values.with_index{|v, i| "#{v}.#{i}"})
assert_equal(h, h.transform_values!{|v|v.to_s})
assert_same(h, h.transform_values!{|v|v.to_s})
assert_equal({a: "1", b: "2", c: "3"}, h)
end
+3 -4
View File
@@ -8,8 +8,7 @@ istruct_test_initialize(mrb_state *mrb, mrb_value self)
{
char *string = (char*)mrb_istruct_ptr(self);
mrb_int size = mrb_istruct_size();
mrb_value object;
mrb_get_args(mrb, "o", &object);
mrb_value object = mrb_get_arg1(mrb);
if (mrb_fixnum_p(object)) {
strncpy(string, "fixnum", size-1);
@@ -45,8 +44,8 @@ istruct_test_length(mrb_state *mrb, mrb_value self)
static mrb_value
istruct_test_test_receive(mrb_state *mrb, mrb_value self)
{
mrb_value object;
mrb_get_args(mrb, "o", &object);
mrb_value object = mrb_get_arg1(mrb);
if (mrb_obj_class(mrb, object) != mrb_class_get(mrb, "InlineStructTest"))
{
mrb_raise(mrb, E_TYPE_ERROR, "Expected InlineStructTest");
+1
View File
@@ -171,6 +171,7 @@ Add the line below to your `build_config.rb`:
## License
Copyright (c) 2013 Internet Initiative Japan Inc.
Copyright (c) 2017 mruby developers
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
+40 -8
View File
@@ -5,10 +5,24 @@
#ifndef MRUBY_IO_H
#define MRUBY_IO_H
#include <mruby.h>
#ifdef MRB_DISABLE_STDIO
# error IO and File conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb'
#endif
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(MRB_WITHOUT_IO_PREAD_PWRITE)
# undef MRB_WITH_IO_PREAD_PWRITE
#elif !defined(MRB_WITH_IO_PREAD_PWRITE)
# if defined(__unix__) || defined(__MACH__)
# define MRB_WITH_IO_PREAD_PWRITE
# endif
#endif
struct mrb_io {
int fd; /* file descriptor, or -1 */
int fd2; /* file descriptor to write if it's different from fd, or -1 */
@@ -19,18 +33,36 @@ struct mrb_io {
is_socket:1;
};
#define FMODE_READABLE 0x00000001
#define FMODE_WRITABLE 0x00000002
#define FMODE_READWRITE (FMODE_READABLE|FMODE_WRITABLE)
#define FMODE_BINMODE 0x00000004
#define FMODE_APPEND 0x00000040
#define FMODE_CREATE 0x00000080
#define FMODE_TRUNC 0x00000800
#define MRB_O_RDONLY 0x0000
#define MRB_O_WRONLY 0x0001
#define MRB_O_RDWR 0x0002
#define MRB_O_ACCMODE (MRB_O_RDONLY | MRB_O_WRONLY | MRB_O_RDWR)
#define MRB_O_NONBLOCK 0x0004
#define MRB_O_APPEND 0x0008
#define MRB_O_SYNC 0x0010
#define MRB_O_NOFOLLOW 0x0020
#define MRB_O_CREAT 0x0040
#define MRB_O_TRUNC 0x0080
#define MRB_O_EXCL 0x0100
#define MRB_O_NOCTTY 0x0200
#define MRB_O_DIRECT 0x0400
#define MRB_O_BINARY 0x0800
#define MRB_O_SHARE_DELETE 0x1000
#define MRB_O_TMPFILE 0x2000
#define MRB_O_NOATIME 0x4000
#define MRB_O_DSYNC 0x00008000
#define MRB_O_RSYNC 0x00010000
#define MRB_O_RDONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDONLY))
#define MRB_O_WRONLY_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_WRONLY))
#define MRB_O_RDWR_P(f) ((mrb_bool)(((f) & MRB_O_ACCMODE) == MRB_O_RDWR))
#define MRB_O_READABLE_P(f) ((mrb_bool)((((f) & MRB_O_ACCMODE) | 2) == 2))
#define MRB_O_WRITABLE_P(f) ((mrb_bool)(((((f) & MRB_O_ACCMODE) + 1) & 2) == 2))
#define E_IO_ERROR (mrb_class_get(mrb, "IOError"))
#define E_EOF_ERROR (mrb_class_get(mrb, "EOFError"))
mrb_value mrb_io_fileno(mrb_state *mrb, mrb_value io);
int mrb_io_fileno(mrb_state *mrb, mrb_value io);
#if defined(__cplusplus)
} /* extern "C" { */
+3 -9
View File
@@ -1,18 +1,12 @@
MRuby::Gem::Specification.new('mruby-io') do |spec|
spec.license = 'MIT'
spec.authors = 'Internet Initiative Japan Inc.'
spec.authors = ['Internet Initiative Japan Inc.', 'mruby developers']
spec.summary = 'IO and File class'
spec.cc.include_paths << "#{build.root}/src"
case RUBY_PLATFORM
when /mingw|mswin|msys/
spec.linker.libraries += ['Ws2_32']
#spec.cc.include_paths += ["C:/Windows/system/include"]
spec.linker.library_paths += ["C:/Windows/system"]
end
if build.kind_of?(MRuby::CrossBuild) && %w(x86_64-w64-mingw32 i686-w64-mingw32).include?(build.host_target)
spec.linker.libraries += ['ws2_32']
if for_windows?
spec.linker.libraries << "ws2_32"
end
spec.add_test_dependency 'mruby-time', core: 'mruby-time'
end
+35 -35
View File
@@ -55,46 +55,46 @@ class File < IO
s
end
def self.expand_path(path, default_dir = '.')
def concat_path(path, base_path)
if path[0] == "/" || path[1] == ':' # Windows root!
expanded_path = path
elsif path[0] == "~"
if (path[1] == "/" || path[1] == nil)
dir = path[1, path.size]
home_dir = _gethome
def self._concat_path(path, base_path)
if path[0] == "/" || path[1] == ':' # Windows root!
expanded_path = path
elsif path[0] == "~"
if (path[1] == "/" || path[1] == nil)
dir = path[1, path.size]
home_dir = _gethome
unless home_dir
raise ArgumentError, "couldn't find HOME environment -- expanding '~'"
end
expanded_path = home_dir
expanded_path += dir if dir
expanded_path += "/"
else
splitted_path = path.split("/")
user = splitted_path[0][1, splitted_path[0].size]
dir = "/" + splitted_path[1, splitted_path.size].join("/")
home_dir = _gethome(user)
unless home_dir
raise ArgumentError, "user #{user} doesn't exist"
end
expanded_path = home_dir
expanded_path += dir if dir
expanded_path += "/"
unless home_dir
raise ArgumentError, "couldn't find HOME environment -- expanding '~'"
end
else
expanded_path = concat_path(base_path, _getwd)
expanded_path += "/" + path
end
expanded_path
expanded_path = home_dir
expanded_path += dir if dir
expanded_path += "/"
else
splitted_path = path.split("/")
user = splitted_path[0][1, splitted_path[0].size]
dir = "/" + splitted_path[1, splitted_path.size].join("/")
home_dir = _gethome(user)
unless home_dir
raise ArgumentError, "user #{user} doesn't exist"
end
expanded_path = home_dir
expanded_path += dir if dir
expanded_path += "/"
end
else
expanded_path = _concat_path(base_path, _getwd)
expanded_path += "/" + path
end
expanded_path = concat_path(path, default_dir)
expanded_path
end
def self.expand_path(path, default_dir = '.')
expanded_path = _concat_path(path, default_dir)
drive_prefix = ""
if File::ALT_SEPARATOR && expanded_path.size > 2 &&
("A".."Z").include?(expanded_path[0].upcase) && expanded_path[1] == ":"
-16
View File
@@ -1,21 +1,5 @@
class File
module Constants
RDONLY = 0
WRONLY = 1
RDWR = 2
NONBLOCK = 4
APPEND = 8
BINARY = 0
SYNC = 128
NOFOLLOW = 256
CREAT = 512
TRUNC = 1024
EXCL = 2048
NOCTTY = 131072
DSYNC = 4194304
FNM_SYSCASE = 0
FNM_NOESCAPE = 1
FNM_PATHNAME = 2
+7 -12
View File
@@ -170,21 +170,16 @@ class IO
end
def _read_buf
return @buf if @buf && @buf.bytesize >= 4 # maximum UTF-8 character is 4 bytes
@buf ||= ""
begin
@buf += sysread(BUF_SIZE)
rescue EOFError => e
raise e if @buf.empty?
end
return @buf if @buf && @buf.bytesize > 0
sysread(BUF_SIZE, @buf)
end
def ungetc(substr)
raise TypeError.new "expect String, got #{substr.class}" unless substr.is_a?(String)
if @buf.empty?
@buf = substr.dup
@buf.replace(substr)
else
@buf = substr + @buf
@buf[0,0] = substr
end
nil
end
@@ -288,15 +283,15 @@ class IO
def readchar
_read_buf
c = @buf[0]
@buf[0] = ""
c
_readchar(@buf)
end
def getc
begin
readchar
rescue EOFError
c = @buf[0]
@buf[0,1]="" if c
nil
end
end
-4
View File
@@ -28,8 +28,4 @@ module Kernel
def gets(*args)
$stdin.gets(*args)
end
def getc(*args)
$stdin.getc(*args)
end
end
+153 -14
View File
@@ -7,12 +7,7 @@
#include "mruby/data.h"
#include "mruby/string.h"
#include "mruby/ext/io.h"
#if MRUBY_RELEASE_NO < 10000
#include "error.h"
#else
#include "mruby/error.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -53,6 +48,7 @@
#if defined(_WIN32) || defined(_WIN64)
#define PATH_SEPARATOR ";"
#define FILE_ALT_SEPARATOR "\\"
#define VOLUME_SEPARATOR ":"
#else
#define PATH_SEPARATOR ":"
#endif
@@ -70,7 +66,15 @@
#define LOCK_UN 8
#endif
#define STAT(p, s) stat(p, s)
#ifndef _WIN32
typedef struct stat mrb_stat;
# define mrb_stat(path, sb) stat(path, sb)
# define mrb_fstat(fd, sb) fstat(fd, sb)
#else
typedef struct __stat64 mrb_stat;
# define mrb_stat(path, sb) _stat64(path, sb)
# define mrb_fstat(fd, sb) _fstat64(fd, sb)
#endif
#ifdef _WIN32
static int
@@ -85,7 +89,7 @@ flock(int fd, int operation) {
}
#endif
mrb_value
static mrb_value
mrb_file_s_umask(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -261,7 +265,7 @@ mrb_file_realpath(mrb_state *mrb, mrb_value klass)
return result;
}
mrb_value
static mrb_value
mrb_file__getwd(mrb_state *mrb, mrb_value klass)
{
mrb_value path;
@@ -276,12 +280,59 @@ mrb_file__getwd(mrb_state *mrb, mrb_value klass)
return path;
}
#ifdef _WIN32
#define IS_FILESEP(x) (x == (*(char*)(FILE_SEPARATOR)) || x == (*(char*)(FILE_ALT_SEPARATOR)))
#define IS_VOLSEP(x) (x == (*(char*)(VOLUME_SEPARATOR)))
#define IS_DEVICEID(x) (x == '.' || x == '?')
#define CHECK_UNCDEV_PATH (IS_FILESEP(path[0]) && IS_FILESEP(path[1]))
static int
is_absolute_traditional_path(const char *path, size_t len)
{
if (len < 3) return 0;
return (ISALPHA(path[0]) && IS_VOLSEP(path[1]) && IS_FILESEP(path[2]));
}
static int
is_aboslute_unc_path(const char *path, size_t len) {
if (len < 2) return 0;
return (CHECK_UNCDEV_PATH && !IS_DEVICEID(path[2]));
}
static int
is_absolute_device_path(const char *path, size_t len) {
if (len < 4) return 0;
return (CHECK_UNCDEV_PATH && IS_DEVICEID(path[2]) && IS_FILESEP(path[3]));
}
static int
mrb_file_is_absolute_path(const char *path)
{
return (path[0] == '/');
size_t len = strlen(path);
if (IS_FILESEP(path[0])) return 1;
if (len > 0)
return (
is_absolute_traditional_path(path, len) ||
is_aboslute_unc_path(path, len) ||
is_absolute_device_path(path, len)
);
else
return 0;
}
#undef IS_FILESEP
#undef IS_VOLSEP
#undef IS_DEVICEID
#undef CHECK_UNCDEV_PATH
#else
static int
mrb_file_is_absolute_path(const char *path)
{
return (path[0] == *(char*)(FILE_SEPARATOR));
}
#endif
static mrb_value
mrb_file__gethome(mrb_state *mrb, mrb_value klass)
{
@@ -316,7 +367,7 @@ mrb_file__gethome(mrb_state *mrb, mrb_value klass)
path = mrb_str_new_cstr(mrb, home);
mrb_locale_free(home);
return path;
#else
#else /* _WIN32 */
argc = mrb_get_argc(mrb);
if (argc == 0) {
home = getenv("USERPROFILE");
@@ -344,13 +395,13 @@ mrb_file_mtime(mrb_state *mrb, mrb_value self)
int fd;
obj = mrb_obj_value(mrb_class_get(mrb, "Time"));
fd = (int)mrb_fixnum(mrb_io_fileno(mrb, self));
fd = mrb_io_fileno(mrb, self);
if (fstat(fd, &st) == -1)
return mrb_false_value();
return mrb_funcall(mrb, obj, "at", 1, mrb_fixnum_value(st.st_mtime));
}
mrb_value
static mrb_value
mrb_file_flock(mrb_state *mrb, mrb_value self)
{
#if defined(sun)
@@ -360,7 +411,7 @@ mrb_file_flock(mrb_state *mrb, mrb_value self)
int fd;
mrb_get_args(mrb, "i", &operation);
fd = (int)mrb_fixnum(mrb_io_fileno(mrb, self));
fd = mrb_io_fileno(mrb, self);
while (flock(fd, (int)operation) == -1) {
switch (errno) {
@@ -384,6 +435,74 @@ mrb_file_flock(mrb_state *mrb, mrb_value self)
return mrb_fixnum_value(0);
}
static mrb_value
mrb_file_size(mrb_state *mrb, mrb_value self)
{
mrb_stat st;
int fd;
fd = mrb_io_fileno(mrb, self);
if (mrb_fstat(fd, &st) == -1) {
mrb_raise(mrb, E_RUNTIME_ERROR, "fstat failed");
}
if (st.st_size > MRB_INT_MAX) {
#ifdef MRB_WITHOUT_FLOAT
mrb_raise(mrb, E_RUNTIME_ERROR, "File#size too large for MRB_WITHOUT_FLOAT");
#else
return mrb_float_value(mrb, (mrb_float)st.st_size);
#endif
}
return mrb_fixnum_value((mrb_int)st.st_size);
}
static int
mrb_ftruncate(int fd, mrb_int length)
{
#ifndef _WIN32
return ftruncate(fd, (off_t)length);
#else
HANDLE file;
__int64 cur;
file = (HANDLE)_get_osfhandle(fd);
if (file == INVALID_HANDLE_VALUE) {
return -1;
}
cur = _lseeki64(fd, 0, SEEK_CUR);
if (cur == -1) return -1;
if (_lseeki64(fd, (__int64)length, SEEK_SET) == -1) return -1;
if (!SetEndOfFile(file)) {
errno = EINVAL; /* TODO: GetLastError to errno */
return -1;
}
if (_lseeki64(fd, cur, SEEK_SET) == -1) return -1;
return 0;
#endif /* _WIN32 */
}
static mrb_value
mrb_file_truncate(mrb_state *mrb, mrb_value self)
{
int fd;
mrb_int length;
mrb_value lenv = mrb_get_arg1(mrb);
fd = mrb_io_fileno(mrb, self);
length = mrb_int(mrb, lenv);
if (mrb_ftruncate(fd, length) != 0) {
mrb_raise(mrb, E_IO_ERROR, "ftruncate failed");
}
return mrb_fixnum_value(0);
}
static mrb_value
mrb_file_s_symlink(mrb_state *mrb, mrb_value klass)
{
@@ -474,7 +593,7 @@ mrb_init_file(mrb_state *mrb)
io = mrb_class_get(mrb, "IO");
file = mrb_define_class(mrb, "File", io);
MRB_SET_INSTANCE_TT(file, MRB_TT_DATA);
mrb_define_class_method(mrb, file, "umask", mrb_file_s_umask, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, file, "umask", mrb_file_s_umask, MRB_ARGS_OPT(1));
mrb_define_class_method(mrb, file, "delete", mrb_file_s_unlink, MRB_ARGS_ANY());
mrb_define_class_method(mrb, file, "unlink", mrb_file_s_unlink, MRB_ARGS_ANY());
mrb_define_class_method(mrb, file, "rename", mrb_file_s_rename, MRB_ARGS_REQ(2));
@@ -490,6 +609,8 @@ mrb_init_file(mrb_state *mrb)
mrb_define_method(mrb, file, "flock", mrb_file_flock, MRB_ARGS_REQ(1));
mrb_define_method(mrb, file, "mtime", mrb_file_mtime, MRB_ARGS_NONE());
mrb_define_method(mrb, file, "size", mrb_file_size, MRB_ARGS_NONE());
mrb_define_method(mrb, file, "truncate", mrb_file_truncate, MRB_ARGS_REQ(1));
cnst = mrb_define_module_under(mrb, file, "Constants");
mrb_define_const(mrb, cnst, "LOCK_SH", mrb_fixnum_value(LOCK_SH));
@@ -505,4 +626,22 @@ mrb_init_file(mrb_state *mrb)
#endif
mrb_define_const(mrb, cnst, "NULL", mrb_str_new_cstr(mrb, NULL_FILE));
mrb_define_const(mrb, cnst, "RDONLY", mrb_fixnum_value(MRB_O_RDONLY));
mrb_define_const(mrb, cnst, "WRONLY", mrb_fixnum_value(MRB_O_WRONLY));
mrb_define_const(mrb, cnst, "RDWR", mrb_fixnum_value(MRB_O_RDWR));
mrb_define_const(mrb, cnst, "APPEND", mrb_fixnum_value(MRB_O_APPEND));
mrb_define_const(mrb, cnst, "CREAT", mrb_fixnum_value(MRB_O_CREAT));
mrb_define_const(mrb, cnst, "EXCL", mrb_fixnum_value(MRB_O_EXCL));
mrb_define_const(mrb, cnst, "TRUNC", mrb_fixnum_value(MRB_O_TRUNC));
mrb_define_const(mrb, cnst, "NONBLOCK", mrb_fixnum_value(MRB_O_NONBLOCK));
mrb_define_const(mrb, cnst, "NOCTTY", mrb_fixnum_value(MRB_O_NOCTTY));
mrb_define_const(mrb, cnst, "BINARY", mrb_fixnum_value(MRB_O_BINARY));
mrb_define_const(mrb, cnst, "SHARE_DELETE", mrb_fixnum_value(MRB_O_SHARE_DELETE));
mrb_define_const(mrb, cnst, "SYNC", mrb_fixnum_value(MRB_O_SYNC));
mrb_define_const(mrb, cnst, "DSYNC", mrb_fixnum_value(MRB_O_DSYNC));
mrb_define_const(mrb, cnst, "RSYNC", mrb_fixnum_value(MRB_O_RSYNC));
mrb_define_const(mrb, cnst, "NOFOLLOW", mrb_fixnum_value(MRB_O_NOFOLLOW));
mrb_define_const(mrb, cnst, "NOATIME", mrb_fixnum_value(MRB_O_NOATIME));
mrb_define_const(mrb, cnst, "DIRECT", mrb_fixnum_value(MRB_O_DIRECT));
mrb_define_const(mrb, cnst, "TMPFILE", mrb_fixnum_value(MRB_O_TMPFILE));
}
+18 -41
View File
@@ -7,12 +7,7 @@
#include "mruby/data.h"
#include "mruby/string.h"
#include "mruby/ext/io.h"
#if MRUBY_RELEASE_NO < 10000
#include "error.h"
#else
#include "mruby/error.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -33,7 +28,6 @@
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -91,7 +85,7 @@ mrb_lstat(mrb_state *mrb, mrb_value obj, struct stat *st)
* File.directory?(".")
*/
mrb_value
static mrb_value
mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
{
#ifndef S_ISDIR
@@ -99,9 +93,7 @@ mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
#endif
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_stat(mrb, obj, &st) < 0)
return mrb_false_value();
@@ -118,7 +110,7 @@ mrb_filetest_s_directory_p(mrb_state *mrb, mrb_value klass)
* Returns <code>true</code> if the named file is a pipe.
*/
mrb_value
static mrb_value
mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -130,9 +122,7 @@ mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
# endif
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_stat(mrb, obj, &st) < 0)
return mrb_false_value();
@@ -151,7 +141,7 @@ mrb_filetest_s_pipe_p(mrb_state *mrb, mrb_value klass)
* Returns <code>true</code> if the named file is a symbolic link.
*/
mrb_value
static mrb_value
mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -173,9 +163,7 @@ mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
#ifdef S_ISLNK
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_lstat(mrb, obj, &st) == -1)
return mrb_false_value();
@@ -194,7 +182,7 @@ mrb_filetest_s_symlink_p(mrb_state *mrb, mrb_value klass)
* Returns <code>true</code> if the named file is a socket.
*/
mrb_value
static mrb_value
mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
{
#if defined(_WIN32) || defined(_WIN64)
@@ -216,9 +204,7 @@ mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
#ifdef S_ISSOCK
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_stat(mrb, obj, &st) < 0)
return mrb_false_value();
@@ -238,13 +224,12 @@ mrb_filetest_s_socket_p(mrb_state *mrb, mrb_value klass)
* Return <code>true</code> if the named file exists.
*/
mrb_value
static mrb_value
mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
{
struct stat st;
mrb_value obj;
mrb_value obj = mrb_get_arg1(mrb);
mrb_get_args(mrb, "o", &obj);
if (mrb_stat(mrb, obj, &st) < 0)
return mrb_false_value();
@@ -259,7 +244,7 @@ mrb_filetest_s_exist_p(mrb_state *mrb, mrb_value klass)
* regular file.
*/
mrb_value
static mrb_value
mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
{
#ifndef S_ISREG
@@ -267,9 +252,7 @@ mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
#endif
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_stat(mrb, obj, &st) < 0)
return mrb_false_value();
@@ -287,13 +270,11 @@ mrb_filetest_s_file_p(mrb_state *mrb, mrb_value klass)
* a zero size.
*/
mrb_value
static mrb_value
mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
{
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_stat(mrb, obj, &st) < 0)
return mrb_false_value();
@@ -312,13 +293,11 @@ mrb_filetest_s_zero_p(mrb_state *mrb, mrb_value klass)
* _file_name_ can be an IO object.
*/
mrb_value
static mrb_value
mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
{
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_stat(mrb, obj, &st) < 0)
mrb_sys_fail(mrb, "mrb_stat");
@@ -334,13 +313,11 @@ mrb_filetest_s_size(mrb_state *mrb, mrb_value klass)
* file otherwise.
*/
mrb_value
static mrb_value
mrb_filetest_s_size_p(mrb_state *mrb, mrb_value klass)
{
struct stat st;
mrb_value obj;
mrb_get_args(mrb, "o", &obj);
mrb_value obj = mrb_get_arg1(mrb);
if (mrb_stat(mrb, obj, &st) < 0)
return mrb_nil_value();
+350 -157
View File
@@ -10,12 +10,7 @@
#include "mruby/string.h"
#include "mruby/variable.h"
#include "mruby/ext/io.h"
#if MRUBY_RELEASE_NO < 10000
#include "error.h"
#else
#include "mruby/error.h"
#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -36,14 +31,21 @@
typedef long ftime_t;
typedef long fsuseconds_t;
typedef int fmode_t;
typedef int mrb_io_read_write_size;
#ifndef O_TMPFILE
#define O_TMPFILE O_TEMPORARY
#endif
#else
#include <sys/wait.h>
#include <sys/time.h>
#include <unistd.h>
typedef size_t fsize_t;
typedef time_t ftime_t;
typedef suseconds_t fsuseconds_t;
typedef mode_t fmode_t;
typedef ssize_t mrb_io_read_write_size;
#endif
#ifdef _MSC_VER
@@ -53,9 +55,14 @@ typedef mrb_int pid_t;
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define OPEN_ACCESS_MODE_FLAGS (O_RDONLY | O_WRONLY | O_RDWR)
#define OPEN_RDONLY_P(f) ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_RDONLY))
#define OPEN_WRONLY_P(f) ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_WRONLY))
#define OPEN_RDWR_P(f) ((mrb_bool)(((f) & OPEN_ACCESS_MODE_FLAGS) == O_RDWR))
#define OPEN_READABLE_P(f) ((mrb_bool)(OPEN_RDONLY_P(f) || OPEN_RDWR_P(f)))
#define OPEN_WRITABLE_P(f) ((mrb_bool)(OPEN_WRONLY_P(f) || OPEN_RDWR_P(f)))
static void mrb_io_free(mrb_state *mrb, void *ptr);
struct mrb_data_type mrb_io_type = { "IO", mrb_io_free };
@@ -63,17 +70,9 @@ struct mrb_data_type mrb_io_type = { "IO", mrb_io_free };
static struct mrb_io *io_get_open_fptr(mrb_state *mrb, mrb_value self);
static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr);
static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags);
static int mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode);
static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet);
#if MRUBY_RELEASE_NO < 10000
static struct RClass *
mrb_module_get(mrb_state *mrb, const char *name)
{
return mrb_class_get(mrb, name);
}
#endif
static struct mrb_io *
io_get_open_fptr(mrb_state *mrb, mrb_value self)
{
@@ -113,30 +112,33 @@ io_set_process_status(mrb_state *mrb, pid_t pid, int status)
static int
mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode)
{
int flags = 0;
int flags;
const char *m = mode;
switch (*m++) {
case 'r':
flags |= FMODE_READABLE;
flags = O_RDONLY;
break;
case 'w':
flags |= FMODE_WRITABLE | FMODE_CREATE | FMODE_TRUNC;
flags = O_WRONLY | O_CREAT | O_TRUNC;
break;
case 'a':
flags |= FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE;
flags = O_WRONLY | O_CREAT | O_APPEND;
break;
default:
mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %s", mode);
flags = 0; /* not reached */
}
while (*m) {
switch (*m++) {
case 'b':
flags |= FMODE_BINMODE;
#ifdef O_BINARY
flags |= O_BINARY;
#endif
break;
case '+':
flags |= FMODE_READWRITE;
flags = (flags & ~OPEN_ACCESS_MODE_FLAGS) | O_RDWR;
break;
case ':':
/* XXX: PASSTHROUGH*/
@@ -149,38 +151,72 @@ mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode)
}
static int
mrb_io_flags_to_modenum(mrb_state *mrb, int flags)
mrb_io_mode_to_flags(mrb_state *mrb, mrb_value mode)
{
int modenum = 0;
if (mrb_nil_p(mode)) {
return mrb_io_modestr_to_flags(mrb, "r");
}
else if (mrb_string_p(mode)) {
return mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
}
else {
int flags = 0;
mrb_int flags0 = mrb_int(mrb, mode);
switch(flags & (FMODE_READABLE|FMODE_WRITABLE|FMODE_READWRITE)) {
case FMODE_READABLE:
modenum = O_RDONLY;
break;
case FMODE_WRITABLE:
modenum = O_WRONLY;
break;
case FMODE_READWRITE:
modenum = O_RDWR;
break;
}
switch (flags0 & MRB_O_ACCMODE) {
case MRB_O_RDONLY:
flags |= O_RDONLY;
break;
case MRB_O_WRONLY:
flags |= O_WRONLY;
break;
case MRB_O_RDWR:
flags |= O_RDWR;
break;
default:
mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal access mode %v", mode);
}
if (flags & FMODE_APPEND) {
modenum |= O_APPEND;
}
if (flags & FMODE_TRUNC) {
modenum |= O_TRUNC;
}
if (flags & FMODE_CREATE) {
modenum |= O_CREAT;
}
if (flags0 & MRB_O_APPEND) flags |= O_APPEND;
if (flags0 & MRB_O_CREAT) flags |= O_CREAT;
if (flags0 & MRB_O_EXCL) flags |= O_EXCL;
if (flags0 & MRB_O_TRUNC) flags |= O_TRUNC;
#ifdef O_NONBLOCK
if (flags0 & MRB_O_NONBLOCK) flags |= O_NONBLOCK;
#endif
#ifdef O_NOCTTY
if (flags0 & MRB_O_NOCTTY) flags |= O_NOCTTY;
#endif
#ifdef O_BINARY
if (flags & FMODE_BINMODE) {
modenum |= O_BINARY;
}
if (flags0 & MRB_O_BINARY) flags |= O_BINARY;
#endif
#ifdef O_SHARE_DELETE
if (flags0 & MRB_O_SHARE_DELETE) flags |= O_SHARE_DELETE;
#endif
#ifdef O_SYNC
if (flags0 & MRB_O_SYNC) flags |= O_SYNC;
#endif
#ifdef O_DSYNC
if (flags0 & MRB_O_DSYNC) flags |= O_DSYNC;
#endif
#ifdef O_RSYNC
if (flags0 & MRB_O_RSYNC) flags |= O_RSYNC;
#endif
#ifdef O_NOFOLLOW
if (flags0 & MRB_O_NOFOLLOW) flags |= O_NOFOLLOW;
#endif
#ifdef O_NOATIME
if (flags0 & MRB_O_NOATIME) flags |= O_NOATIME;
#endif
#ifdef O_DIRECT
if (flags0 & MRB_O_DIRECT) flags |= O_DIRECT;
#endif
#ifdef O_TMPFILE
if (flags0 & MRB_O_TMPFILE) flags |= O_TMPFILE;
#endif
return modenum;
return flags;
}
}
static void
@@ -284,16 +320,17 @@ mrb_io_alloc(mrb_state *mrb)
#endif
static int
option_to_fd(mrb_state *mrb, mrb_value obj, const char *key)
option_to_fd(mrb_state *mrb, mrb_value hash, const char *key)
{
mrb_value opt = mrb_funcall(mrb, obj, "[]", 1, mrb_symbol_value(mrb_intern_static(mrb, key, strlen(key))));
if (mrb_nil_p(opt)) {
return -1;
}
mrb_value opt;
if (!mrb_hash_p(hash)) return -1;
opt = mrb_hash_fetch(mrb, hash, mrb_symbol_value(mrb_intern_static(mrb, key, strlen(key))), mrb_nil_value());
if (mrb_nil_p(opt)) return -1;
switch (mrb_type(opt)) {
case MRB_TT_DATA: /* IO */
return (int)mrb_fixnum(mrb_io_fileno(mrb, opt));
return mrb_io_fileno(mrb, opt);
case MRB_TT_FIXNUM:
return (int)mrb_fixnum(opt);
default:
@@ -304,7 +341,7 @@ option_to_fd(mrb_state *mrb, mrb_value obj, const char *key)
}
#ifdef _WIN32
mrb_value
static mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
mrb_value cmd, io;
@@ -329,11 +366,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
ofd[0] = INVALID_HANDLE_VALUE;
ofd[1] = INVALID_HANDLE_VALUE;
mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt);
io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
pname = RSTRING_CSTR(mrb, cmd);
flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
flags = mrb_io_mode_to_flags(mrb, mode);
doexec = (strcmp("-", pname) != 0);
opt_in = option_to_fd(mrb, opt, "in");
@@ -344,14 +381,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (flags & FMODE_READABLE) {
if (OPEN_READABLE_P(flags)) {
if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0)
|| !SetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) {
mrb_sys_fail(mrb, "pipe");
}
}
if (flags & FMODE_WRITABLE) {
if (OPEN_WRITABLE_P(flags)) {
if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0)
|| !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) {
mrb_sys_fail(mrb, "pipe");
@@ -365,11 +402,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
si.dwFlags |= STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.dwFlags |= STARTF_USESTDHANDLES;
if (flags & FMODE_READABLE) {
if (OPEN_READABLE_P(flags)) {
si.hStdOutput = ofd[1];
si.hStdError = ofd[1];
}
if (flags & FMODE_WRITABLE) {
if (OPEN_WRITABLE_P(flags)) {
si.hStdInput = ifd[0];
}
if (!CreateProcess(
@@ -393,8 +430,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0);
fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0);
fptr->pid = pid;
fptr->readable = ((flags & FMODE_READABLE) != 0);
fptr->writable = ((flags & FMODE_WRITABLE) != 0);
fptr->readable = OPEN_READABLE_P(flags);
fptr->writable = OPEN_WRITABLE_P(flags);
fptr->sync = 0;
DATA_TYPE(io) = &mrb_io_type;
@@ -402,14 +439,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
return io;
}
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
mrb_value
static mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
mrb_raise(mrb, E_NOTIMP_ERROR, "IO#popen is not supported on the platform");
return mrb_false_value();
}
#else
mrb_value
static mrb_value
mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
{
mrb_value cmd, io, result;
@@ -425,18 +462,18 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
int saved_errno;
int opt_in, opt_out, opt_err;
mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt);
mrb_get_args(mrb, "S|oH", &cmd, &mode, &opt);
io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type));
pname = RSTRING_CSTR(mrb, cmd);
flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
flags = mrb_io_mode_to_flags(mrb, mode);
doexec = (strcmp("-", pname) != 0);
opt_in = option_to_fd(mrb, opt, "in");
opt_out = option_to_fd(mrb, opt, "out");
opt_err = option_to_fd(mrb, opt, "err");
if (flags & FMODE_READABLE) {
if (OPEN_READABLE_P(flags)) {
if (pipe(pr) == -1) {
mrb_sys_fail(mrb, "pipe");
}
@@ -444,7 +481,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
mrb_fd_cloexec(mrb, pr[1]);
}
if (flags & FMODE_WRITABLE) {
if (OPEN_WRITABLE_P(flags)) {
if (pipe(pw) == -1) {
if (pr[0] != -1) close(pr[0]);
if (pr[1] != -1) close(pr[1]);
@@ -473,14 +510,14 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
if (opt_err != -1) {
dup2(opt_err, 2);
}
if (flags & FMODE_READABLE) {
if (OPEN_READABLE_P(flags)) {
close(pr[0]);
if (pr[1] != 1) {
dup2(pr[1], 1);
close(pr[1]);
}
}
if (flags & FMODE_WRITABLE) {
if (OPEN_WRITABLE_P(flags)) {
close(pw[1]);
if (pw[0] != 0) {
dup2(pw[0], 0);
@@ -499,12 +536,12 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
break;
default: /* parent */
if ((flags & FMODE_READABLE) && (flags & FMODE_WRITABLE)) {
if (OPEN_RDWR_P(flags)) {
close(pr[1]);
fd = pr[0];
close(pw[0]);
write_fd = pw[1];
} else if (flags & FMODE_READABLE) {
} else if (OPEN_RDONLY_P(flags)) {
close(pr[1]);
fd = pr[0];
} else {
@@ -518,8 +555,8 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
fptr->fd = fd;
fptr->fd2 = write_fd;
fptr->pid = pid;
fptr->readable = ((flags & FMODE_READABLE) != 0);
fptr->writable = ((flags & FMODE_WRITABLE) != 0);
fptr->readable = OPEN_READABLE_P(flags);
fptr->writable = OPEN_WRITABLE_P(flags);
fptr->sync = 0;
DATA_TYPE(io) = &mrb_io_type;
@@ -529,11 +566,11 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
case -1: /* error */
saved_errno = errno;
if (flags & FMODE_READABLE) {
if (OPEN_READABLE_P(flags)) {
close(pr[0]);
close(pr[1]);
}
if (flags & FMODE_WRITABLE) {
if (OPEN_WRITABLE_P(flags)) {
close(pw[0]);
close(pw[1]);
}
@@ -559,16 +596,15 @@ mrb_dup(mrb_state *mrb, int fd, mrb_bool *failed)
return new_fd;
}
mrb_value
static mrb_value
mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
{
mrb_value orig;
mrb_value orig = mrb_get_arg1(mrb);
mrb_value buf;
struct mrb_io *fptr_copy;
struct mrb_io *fptr_orig;
mrb_bool failed = TRUE;
mrb_get_args(mrb, "o", &orig);
fptr_orig = io_get_open_fptr(mrb, orig);
fptr_copy = (struct mrb_io *)DATA_PTR(copy);
if (fptr_orig == fptr_copy) return copy;
@@ -608,7 +644,44 @@ mrb_io_initialize_copy(mrb_state *mrb, mrb_value copy)
return copy;
}
mrb_value
static void
check_file_descriptor(mrb_state *mrb, mrb_int fd)
{
struct stat sb;
int fdi = (int)fd;
#if MRB_INT_MIN < INT_MIN || MRB_INT_MAX > INT_MAX
if (fdi != fd) {
goto badfd;
}
#endif
#ifdef _WIN32
{
DWORD err;
int len = sizeof(err);
if (getsockopt(fdi, SOL_SOCKET, SO_ERROR, (char*)&err, &len) == 0) {
return;
}
}
if (fdi < 0 || fdi > _getmaxstdio()) {
goto badfd;
}
#endif /* _WIN32 */
if (fstat(fdi, &sb) != 0) {
goto badfd;
}
return;
badfd:
mrb_sys_fail(mrb, "bad file descriptor");
}
static mrb_value
mrb_io_initialize(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -618,7 +691,8 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
mode = opt = mrb_nil_value();
mrb_get_args(mrb, "i|So", &fd, &mode, &opt);
mrb_get_args(mrb, "i|oo", &fd, &mode, &opt);
check_file_descriptor(mrb, fd);
if (mrb_nil_p(mode)) {
mode = mrb_str_new_cstr(mrb, "r");
}
@@ -626,7 +700,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
opt = mrb_hash_new(mrb);
}
flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
flags = mrb_io_mode_to_flags(mrb, mode);
mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, ""));
@@ -641,8 +715,8 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
DATA_PTR(io) = fptr;
fptr->fd = (int)fd;
fptr->readable = ((flags & FMODE_READABLE) != 0);
fptr->writable = ((flags & FMODE_WRITABLE) != 0);
fptr->readable = OPEN_READABLE_P(flags);
fptr->writable = OPEN_WRITABLE_P(flags);
fptr->sync = 0;
return io;
}
@@ -710,7 +784,7 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
}
}
mrb_value
static mrb_value
mrb_io_check_readable(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr = io_get_open_fptr(mrb, self);
@@ -720,7 +794,7 @@ mrb_io_check_readable(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
mrb_value
static mrb_value
mrb_io_isatty(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -731,7 +805,7 @@ mrb_io_isatty(mrb_state *mrb, mrb_value self)
return mrb_true_value();
}
mrb_value
static mrb_value
mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
{
struct RClass *c = mrb_class_ptr(klass);
@@ -744,7 +818,7 @@ mrb_io_s_for_fd(mrb_state *mrb, mrb_value klass)
return mrb_io_initialize(mrb, obj);
}
mrb_value
static mrb_value
mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
{
mrb_int fd;
@@ -755,7 +829,7 @@ mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
return mrb_fixnum_value(0);
}
int
static int
mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode)
{
int fd, retry = FALSE;
@@ -790,39 +864,55 @@ reopen:
return fd;
}
mrb_value
static mrb_value
mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass)
{
mrb_value path = mrb_nil_value();
mrb_value mode = mrb_nil_value();
mrb_int fd, perm = -1;
const char *pat;
int flags, modenum;
int flags;
mrb_get_args(mrb, "S|Si", &path, &mode, &perm);
if (mrb_nil_p(mode)) {
mode = mrb_str_new_cstr(mrb, "r");
}
mrb_get_args(mrb, "S|oi", &path, &mode, &perm);
if (perm < 0) {
perm = 0666;
}
pat = RSTRING_CSTR(mrb, path);
flags = mrb_io_modestr_to_flags(mrb, RSTRING_CSTR(mrb, mode));
modenum = mrb_io_flags_to_modenum(mrb, flags);
fd = mrb_cloexec_open(mrb, pat, modenum, perm);
flags = mrb_io_mode_to_flags(mrb, mode);
fd = mrb_cloexec_open(mrb, pat, flags, perm);
return mrb_fixnum_value(fd);
}
mrb_value
static mrb_value mrb_io_sysread_common(mrb_state *mrb,
mrb_io_read_write_size (*readfunc)(int, void *, fsize_t, off_t),
mrb_value io, mrb_value buf, mrb_int maxlen, off_t offset);
static mrb_io_read_write_size
mrb_sysread_dummy(int fd, void *buf, fsize_t nbytes, off_t offset)
{
return (mrb_io_read_write_size)read(fd, buf, nbytes);
}
static mrb_value
mrb_io_sysread(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
mrb_value buf = mrb_nil_value();
mrb_int maxlen;
int ret;
mrb_get_args(mrb, "i|S", &maxlen, &buf);
return mrb_io_sysread_common(mrb, mrb_sysread_dummy, io, buf, maxlen, 0);
}
static mrb_value
mrb_io_sysread_common(mrb_state *mrb,
mrb_io_read_write_size (*readfunc)(int, void *, fsize_t, off_t),
mrb_value io, mrb_value buf, mrb_int maxlen, off_t offset)
{
struct mrb_io *fptr;
int ret;
if (maxlen < 0) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "negative expanding string size");
}
@@ -836,7 +926,8 @@ mrb_io_sysread(mrb_state *mrb, mrb_value io)
if (RSTRING_LEN(buf) != maxlen) {
buf = mrb_str_resize(mrb, buf, maxlen);
} else {
}
else {
mrb_str_modify(mrb, RSTRING(buf));
}
@@ -844,29 +935,20 @@ mrb_io_sysread(mrb_state *mrb, mrb_value io)
if (!fptr->readable) {
mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
}
ret = read(fptr->fd, RSTRING_PTR(buf), (fsize_t)maxlen);
switch (ret) {
case 0: /* EOF */
if (maxlen == 0) {
buf = mrb_str_new_cstr(mrb, "");
} else {
mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
}
break;
case -1: /* Error */
mrb_sys_fail(mrb, "sysread failed");
break;
default:
if (RSTRING_LEN(buf) != ret) {
buf = mrb_str_resize(mrb, buf, ret);
}
break;
ret = readfunc(fptr->fd, RSTRING_PTR(buf), (fsize_t)maxlen, offset);
if (ret < 0) {
mrb_sys_fail(mrb, "sysread failed");
}
if (RSTRING_LEN(buf) != ret) {
buf = mrb_str_resize(mrb, buf, ret);
}
if (ret == 0 && maxlen > 0) {
mrb_raise(mrb, E_EOF_ERROR, "sysread failed: End of File");
}
return buf;
}
mrb_value
static mrb_value
mrb_io_sysseek(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -894,11 +976,12 @@ mrb_io_sysseek(mrb_state *mrb, mrb_value io)
}
}
mrb_value
mrb_io_syswrite(mrb_state *mrb, mrb_value io)
static mrb_value
mrb_io_syswrite_common(mrb_state *mrb,
mrb_io_read_write_size (*writefunc)(int, const void *, fsize_t, off_t),
mrb_value io, mrb_value buf, off_t offset)
{
struct mrb_io *fptr;
mrb_value str, buf;
int fd, length;
fptr = io_get_open_fptr(mrb, io);
@@ -906,19 +989,12 @@ mrb_io_syswrite(mrb_state *mrb, mrb_value io)
mrb_raise(mrb, E_IO_ERROR, "not opened for writing");
}
mrb_get_args(mrb, "S", &str);
if (!mrb_string_p(str)) {
buf = mrb_funcall(mrb, str, "to_s", 0);
} else {
buf = str;
}
if (fptr->fd2 == -1) {
fd = fptr->fd;
} else {
fd = fptr->fd2;
}
length = write(fd, RSTRING_PTR(buf), (fsize_t)RSTRING_LEN(buf));
length = writefunc(fd, RSTRING_PTR(buf), (fsize_t)RSTRING_LEN(buf), offset);
if (length == -1) {
mrb_sys_fail(mrb, 0);
}
@@ -926,7 +1002,23 @@ mrb_io_syswrite(mrb_state *mrb, mrb_value io)
return mrb_fixnum_value(length);
}
mrb_value
static mrb_io_read_write_size
mrb_syswrite_dummy(int fd, const void *buf, fsize_t nbytes, off_t offset)
{
return (mrb_io_read_write_size)write(fd, buf, nbytes);
}
static mrb_value
mrb_io_syswrite(mrb_state *mrb, mrb_value io)
{
mrb_value buf;
mrb_get_args(mrb, "S", &buf);
return mrb_io_syswrite_common(mrb, mrb_syswrite_dummy, io, buf, 0);
}
static mrb_value
mrb_io_close(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -935,7 +1027,7 @@ mrb_io_close(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
mrb_value
static mrb_value
mrb_io_close_write(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -946,7 +1038,7 @@ mrb_io_close_write(mrb_state *mrb, mrb_value self)
return mrb_nil_value();
}
mrb_value
static mrb_value
mrb_io_closed(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -958,7 +1050,7 @@ mrb_io_closed(mrb_state *mrb, mrb_value io)
return mrb_true_value();
}
mrb_value
static mrb_value
mrb_io_pid(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
@@ -1063,7 +1155,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
mrb_get_args(mrb, "*", &argv, &argc);
if (argc < 1 || argc > 4) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%i for 1..4)", argc);
mrb_argnum_error(mrb, argc, 1, 4);
}
timeout = mrb_nil_value();
@@ -1092,6 +1184,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
for (i = 0; i < RARRAY_LEN(read); i++) {
read_io = RARRAY_PTR(read)[i];
fptr = io_get_open_fptr(mrb, read_io);
if (fptr->fd >= FD_SETSIZE) continue;
FD_SET(fptr->fd, rp);
if (mrb_io_read_data_pending(mrb, read_io)) {
pending++;
@@ -1114,6 +1207,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
FD_ZERO(wp);
for (i = 0; i < RARRAY_LEN(write); i++) {
fptr = io_get_open_fptr(mrb, RARRAY_PTR(write)[i]);
if (fptr->fd >= FD_SETSIZE) continue;
FD_SET(fptr->fd, wp);
if (max < fptr->fd)
max = fptr->fd;
@@ -1133,6 +1227,7 @@ mrb_io_s_select(mrb_state *mrb, mrb_value klass)
FD_ZERO(ep);
for (i = 0; i < RARRAY_LEN(except); i++) {
fptr = io_get_open_fptr(mrb, RARRAY_PTR(except)[i]);
if (fptr->fd >= FD_SETSIZE) continue;
FD_SET(fptr->fd, ep);
if (max < fptr->fd)
max = fptr->fd;
@@ -1206,15 +1301,22 @@ retry:
return result;
}
mrb_value
int
mrb_io_fileno(mrb_state *mrb, mrb_value io)
{
struct mrb_io *fptr;
fptr = io_get_open_fptr(mrb, io);
return mrb_fixnum_value(fptr->fd);
return fptr->fd;
}
mrb_value
static mrb_value
mrb_io_fileno_m(mrb_state *mrb, mrb_value io)
{
int fd = mrb_io_fileno(mrb, io);
return mrb_fixnum_value(fd);
}
static mrb_value
mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
{
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
@@ -1238,7 +1340,7 @@ mrb_io_close_on_exec_p(mrb_state *mrb, mrb_value self)
#endif
}
mrb_value
static mrb_value
mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
{
#if defined(F_GETFD) && defined(F_SETFD) && defined(FD_CLOEXEC)
@@ -1274,7 +1376,7 @@ mrb_io_set_close_on_exec(mrb_state *mrb, mrb_value self)
#endif
}
mrb_value
static mrb_value
mrb_io_set_sync(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -1286,7 +1388,7 @@ mrb_io_set_sync(mrb_state *mrb, mrb_value self)
return mrb_bool_value(b);
}
mrb_value
static mrb_value
mrb_io_sync(mrb_state *mrb, mrb_value self)
{
struct mrb_io *fptr;
@@ -1294,15 +1396,55 @@ mrb_io_sync(mrb_state *mrb, mrb_value self)
return mrb_bool_value(fptr->sync);
}
static mrb_value
io_bufread(mrb_state *mrb, mrb_value self)
#ifndef MRB_WITH_IO_PREAD_PWRITE
# define mrb_io_pread mrb_notimplement_m
# define mrb_io_pwrite mrb_notimplement_m
#else
static off_t
value2off(mrb_state *mrb, mrb_value offv)
{
mrb_value str, str2;
mrb_int len, newlen;
return (off_t)mrb_int(mrb, offv);
}
/*
* call-seq:
* pread(maxlen, offset, outbuf = "") -> outbuf
*/
static mrb_value
mrb_io_pread(mrb_state *mrb, mrb_value io)
{
mrb_value buf = mrb_nil_value();
mrb_value off;
mrb_int maxlen;
mrb_get_args(mrb, "io|S!", &maxlen, &off, &buf);
return mrb_io_sysread_common(mrb, pread, io, buf, maxlen, value2off(mrb, off));
}
/*
* call-seq:
* pwrite(buffer, offset) -> wrote_bytes
*/
static mrb_value
mrb_io_pwrite(mrb_state *mrb, mrb_value io)
{
mrb_value buf, off;
mrb_get_args(mrb, "So", &buf, &off);
return mrb_io_syswrite_common(mrb, pwrite, io, buf, value2off(mrb, off));
}
#endif /* MRB_WITH_IO_PREAD_PWRITE */
static mrb_value
io_bufread(mrb_state *mrb, mrb_value str, mrb_int len)
{
mrb_value str2;
mrb_int newlen;
struct RString *s;
char *p;
mrb_get_args(mrb, "Si", &str, &len);
s = RSTRING(str);
mrb_str_modify(mrb, s);
p = RSTR_PTR(s);
@@ -1315,6 +1457,54 @@ io_bufread(mrb_state *mrb, mrb_value self)
return str2;
}
static mrb_value
mrb_io_bufread(mrb_state *mrb, mrb_value self)
{
mrb_value str;
mrb_int len;
mrb_get_args(mrb, "Si", &str, &len);
return io_bufread(mrb, str, len);
}
static mrb_value
mrb_io_readchar(mrb_state *mrb, mrb_value self)
{
mrb_value buf;
mrb_int len = 1;
#ifdef MRB_UTF8_STRING
unsigned char c;
#endif
mrb_get_args(mrb, "S", &buf);
mrb_assert(RSTRING_LEN(buf) > 0);
mrb_assert(RSTRING_PTR(buf) != NULL);
mrb_str_modify(mrb, RSTRING(buf));
#ifdef MRB_UTF8_STRING
c = RSTRING_PTR(buf)[0];
if (c & 0x80) {
len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf));
if (len == 1 && RSTRING_LEN(buf) < 4) { /* partial UTF-8 */
mrb_int blen = RSTRING_LEN(buf);
ssize_t n;
struct mrb_io *fptr = (struct mrb_io*)io_get_open_fptr(mrb, self);
if (!fptr->readable) {
mrb_raise(mrb, E_IO_ERROR, "not opened for reading");
}
/* refill the buffer */
mrb_str_resize(mrb, buf, 4096);
n = read(fptr->fd, RSTRING_PTR(buf)+blen, 4096-blen);
if (n < 0) mrb_sys_fail(mrb, "sysread failed");
mrb_str_resize(mrb, buf, blen+n);
}
len = mrb_utf8len(RSTRING_PTR(buf), RSTRING_END(buf));
}
#endif
return io_bufread(mrb, buf, len);
}
void
mrb_init_io(mrb_state *mrb)
{
@@ -1324,23 +1514,23 @@ mrb_init_io(mrb_state *mrb)
MRB_SET_INSTANCE_TT(io, MRB_TT_DATA);
mrb_include_module(mrb, io, mrb_module_get(mrb, "Enumerable")); /* 15.2.20.3 */
mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ANY());
mrb_define_class_method(mrb, io, "_popen", mrb_io_s_popen, MRB_ARGS_ARG(1,2));
mrb_define_class_method(mrb, io, "_sysclose", mrb_io_s_sysclose, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_ANY());
mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ANY());
mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ANY());
mrb_define_class_method(mrb, io, "for_fd", mrb_io_s_for_fd, MRB_ARGS_ARG(1,2));
mrb_define_class_method(mrb, io, "select", mrb_io_s_select, MRB_ARGS_ARG(1,3));
mrb_define_class_method(mrb, io, "sysopen", mrb_io_s_sysopen, MRB_ARGS_ARG(1,2));
#if !defined(_WIN32) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
mrb_define_class_method(mrb, io, "_pipe", mrb_io_s_pipe, MRB_ARGS_NONE());
#endif
mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ANY()); /* 15.2.20.5.21 (x)*/
mrb_define_method(mrb, io, "initialize", mrb_io_initialize, MRB_ARGS_ARG(1,2)); /* 15.2.20.5.21 (x)*/
mrb_define_method(mrb, io, "initialize_copy", mrb_io_initialize_copy, MRB_ARGS_REQ(1));
mrb_define_method(mrb, io, "_check_readable", mrb_io_check_readable, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "isatty", mrb_io_isatty, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "sync", mrb_io_sync, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "sync=", mrb_io_set_sync, MRB_ARGS_REQ(1));
mrb_define_method(mrb, io, "sysread", mrb_io_sysread, MRB_ARGS_ANY());
mrb_define_method(mrb, io, "sysseek", mrb_io_sysseek, MRB_ARGS_REQ(1));
mrb_define_method(mrb, io, "sysread", mrb_io_sysread, MRB_ARGS_ARG(1,1));
mrb_define_method(mrb, io, "sysseek", mrb_io_sysseek, MRB_ARGS_ARG(1,1));
mrb_define_method(mrb, io, "syswrite", mrb_io_syswrite, MRB_ARGS_REQ(1));
mrb_define_method(mrb, io, "close", mrb_io_close, MRB_ARGS_NONE()); /* 15.2.20.5.1 */
mrb_define_method(mrb, io, "close_write", mrb_io_close_write, MRB_ARGS_NONE());
@@ -1348,7 +1538,10 @@ mrb_init_io(mrb_state *mrb)
mrb_define_method(mrb, io, "close_on_exec?", mrb_io_close_on_exec_p, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "closed?", mrb_io_closed, MRB_ARGS_NONE()); /* 15.2.20.5.2 */
mrb_define_method(mrb, io, "pid", mrb_io_pid, MRB_ARGS_NONE()); /* 15.2.20.5.2 */
mrb_define_method(mrb, io, "fileno", mrb_io_fileno, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "fileno", mrb_io_fileno_m, MRB_ARGS_NONE());
mrb_define_method(mrb, io, "pread", mrb_io_pread, MRB_ARGS_ANY()); /* ruby 2.5 feature */
mrb_define_method(mrb, io, "pwrite", mrb_io_pwrite, MRB_ARGS_ANY()); /* ruby 2.5 feature */
mrb_define_class_method(mrb, io, "_bufread", io_bufread, MRB_ARGS_REQ(2));
mrb_define_method(mrb, io, "_readchar", mrb_io_readchar, MRB_ARGS_REQ(1));
mrb_define_class_method(mrb, io, "_bufread", mrb_io_bufread, MRB_ARGS_REQ(2));
}
+34 -12
View File
@@ -80,6 +80,22 @@ assert('File#mtime') do
end
end
assert('File#size and File#truncate') do
fname = "#{$mrbtest_io_wfname}.resize"
begin
File.open(fname, 'w') do |f|
assert_equal 0, f.size
assert_equal 0, f.truncate(100)
assert_equal 100, f.size
assert_equal 0, f.pos
assert_equal 0, f.truncate(5)
assert_equal 5, f.size
end
ensure
File.delete(fname)
end
end
assert('File.join') do
assert_equal "", File.join()
assert_equal "a", File.join("a")
@@ -94,18 +110,22 @@ assert('File.join') do
end
assert('File.realpath') do
if File::ALT_SEPARATOR
readme_path = File._getwd + File::ALT_SEPARATOR + "README.md"
assert_equal readme_path, File.realpath("README.md")
else
dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
begin
dir1 = File.realpath($mrbtest_io_rfname)
dir2 = File.realpath("./#{dir}//./../#{$mrbtest_io_symlinkname}")
assert_equal dir1, dir2
ensure
MRubyIOTestUtil.rmdir dir
dir = MRubyIOTestUtil.mkdtemp("mruby-io-test.XXXXXX")
begin
sep = File::ALT_SEPARATOR || File::SEPARATOR
relative_path = "#{File.basename(dir)}#{sep}realpath_test"
path = "#{File._getwd}#{sep}#{relative_path}"
File.open(path, "w"){}
assert_equal path, File.realpath(relative_path)
unless MRubyIOTestUtil.win?
path1 = File.realpath($mrbtest_io_rfname)
path2 = File.realpath($mrbtest_io_symlinkname)
assert_equal path1, path2
end
ensure
File.delete path rescue nil
MRubyIOTestUtil.rmdir dir
end
assert_raise(ArgumentError) { File.realpath("TO\0DO") }
@@ -113,7 +133,9 @@ end
assert("File.readlink") do
begin
assert_equal $mrbtest_io_rfname, File.readlink($mrbtest_io_symlinkname)
exp = File.basename($mrbtest_io_rfname)
act = File.readlink($mrbtest_io_symlinkname)
assert_equal exp, act
rescue NotImplementedError => e
skip e.message
end
+32
View File
@@ -24,6 +24,10 @@ def assert_io_open(meth)
end
end
io2.close unless meth == :open
assert_raise(RuntimeError) { IO.__send__(meth, 1023) } # For Windows
assert_raise(RuntimeError) { IO.__send__(meth, 1 << 26) }
assert_raise(RuntimeError) { IO.__send__(meth, 1 << 32) } if (1 << 32).kind_of?(Integer)
end
end
@@ -564,6 +568,34 @@ assert('IO#sysseek') do
end
end
assert('IO#pread') do
skip "IO#pread is not implemented on this configuration" unless MRubyIOTestUtil::MRB_WITH_IO_PREAD_PWRITE
IO.open(IO.sysopen($mrbtest_io_rfname, 'r'), 'r') do |io|
assert_equal $mrbtest_io_msg.byteslice(5, 8), io.pread(8, 5)
assert_equal 0, io.pos
assert_equal $mrbtest_io_msg.byteslice(1, 5), io.pread(5, 1)
assert_equal 0, io.pos
assert_raise(RuntimeError) { io.pread(20, -9) }
end
end
assert('IO#pwrite') do
skip "IO#pwrite is not implemented on this configuration" unless MRubyIOTestUtil::MRB_WITH_IO_PREAD_PWRITE
IO.open(IO.sysopen($mrbtest_io_wfname, 'w+'), 'w+') do |io|
assert_equal 6, io.pwrite("Warld!", 7)
assert_equal 0, io.pos
assert_equal 7, io.pwrite("Hello, ", 0)
assert_equal 0, io.pos
assert_equal "Hello, Warld!", io.read
assert_equal 6, io.pwrite("world!", 7)
assert_equal 13, io.pos
io.pos = 0
assert_equal "Hello, world!", io.read
end
end
assert('IO.pipe') do
begin
called = false

Some files were not shown because too many files have changed in this diff Show More