Commit 70c344bb authored by Philip Chimento's avatar Philip Chimento 🚮

Merge branch '161-mozjs60' into 'master'

Resolve "Port to SpiderMonkey 60"

Closes #161 and #5

See merge request !199
parents f2a8ca3d 796c83b8
Pipeline #22187 passed with stages
in 22 minutes and 38 seconds
......@@ -129,7 +129,7 @@ stages:
fedora:
<<: *build
stage: source_check
image: registry.gitlab.gnome.org/gnome/gjs:job-68368_SM52-debug-gcc.fedora-dev # pinned on purpose
image: registry.gitlab.gnome.org/gnome/gjs:job-70238_SM60-debug-gcc.fedora-dev # pinned on purpose
variables:
TASK_ID: "fedora-x86_64-gcc-debug-default-check"
TEST: "check"
......@@ -140,7 +140,7 @@ fedora:
sanitizer_gcc:
<<: *build
stage: test
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-ubsan_asan-check"
BUILD_OPTS: "--enable-asan --enable-ubsan"
......@@ -154,7 +154,7 @@ sanitizer_gcc:
with_logging:
<<: *build
stage: test
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "ubuntu-x86_64-clang-default-logging-check"
CC: clang
......@@ -168,7 +168,7 @@ with_logging:
no_graphics:
<<: *build
stage: test
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-without_gtk-check"
TEST: "check"
......@@ -180,7 +180,7 @@ no_graphics:
no_profiler:
<<: *build
stage: test
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-disable_profiler-check"
TEST: "check"
......@@ -191,7 +191,7 @@ no_profiler:
no_readline:
<<: *build
stage: test
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-disable_readline-check"
TEST: "check"
......@@ -205,7 +205,7 @@ coverage-automatic:
<<: *build
<<: *coverage
stage: source_check
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "coverage"
BUILD_OPTS: "--enable-code-coverage"
......@@ -308,7 +308,7 @@ code_statistics:
sanitizer_clang:
<<: *build
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "ubuntu-x86_64-clang_ubsan_asan-default-default-check"
CC: clang
......@@ -321,7 +321,7 @@ sanitizer_clang:
fedora_gcc:
<<: *build
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-default-distcheck"
TEST: "distcheck"
......@@ -332,7 +332,7 @@ fedora_gcc:
installed_tests:
<<: *build
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-default-installed_tests"
BUILD_OPTS: "--enable-installed-tests --prefix=/usr"
......@@ -346,7 +346,7 @@ installed_tests:
ubuntu_gcc:
<<: *build
stage: source_check
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "ubuntu-x86_64-gcc-default-default-distcheck"
TEST: "distcheck"
......@@ -357,7 +357,7 @@ ubuntu_gcc:
ubuntu_clang:
<<: *build
stage: source_check
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "ubuntu-x86_64-clang-default-default-distcheck"
CC: clang
......@@ -370,7 +370,7 @@ lts:
<<: *build
<<: *jhbuild
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-lts
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-lts
variables:
TASK_ID: "ubuntu_lts-x86_64-gcc-default-default-check"
DEV: jhbuild
......@@ -382,7 +382,7 @@ lts:
valgrind:
<<: *build
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-default-valgrind_check"
BUILD_OPTS: "--enable-valgrind --disable-valgrind-helgrind --prefix=/usr"
......@@ -421,7 +421,7 @@ flatpak:
zeal_2:
<<: *build
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-debug-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-debug-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-debug-default-check_zeal2"
TEST: "check"
......@@ -433,7 +433,7 @@ zeal_2:
zeal_4:
<<: *build
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-debug-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-debug-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-debug-default-check_zeal4"
TEST: "check"
......@@ -445,7 +445,7 @@ zeal_4:
zeal_11:
<<: *build
stage: thorough_tests
image: registry.gitlab.gnome.org/gnome/gjs:SM52-debug-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-debug-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-debug-default-check_zeal11"
TEST: "check"
......@@ -463,7 +463,7 @@ armv8:
variables:
TASK_ID: "fedora-armv8-gcc-default-default-check"
DOCKER_DRIVER: overlay
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev.aarch64"
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev.aarch64"
only:
variables:
- $CRON_FREQUENCY == "Weekly"
......@@ -474,7 +474,7 @@ ppc64le:
variables:
TASK_ID: "fedora-ppc64le-gcc-default-default-check"
DOCKER_DRIVER: overlay
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev.ppc64le"
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev.ppc64le"
only:
variables:
- $CRON_FREQUENCY == "Weekly"
......@@ -515,7 +515,7 @@ coverage:
<<: *build
<<: *coverage
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "coverage"
BUILD_OPTS: "--enable-code-coverage"
......@@ -527,7 +527,7 @@ coverage:
sanitizer_clang:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "ubuntu-x86_64-clang_ubsan_asan-default-default-check"
CC: clang
......@@ -540,7 +540,7 @@ sanitizer_clang:
fedora_gcc:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-default-distcheck"
TEST: "distcheck"
......@@ -551,7 +551,7 @@ fedora_gcc:
installed_tests:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-default-installed_tests"
BUILD_OPTS: "--enable-installed-tests --prefix=/usr"
......@@ -563,7 +563,7 @@ installed_tests:
ubuntu_gcc:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "ubuntu-x86_64-gcc-default-default-distcheck"
TEST: "distcheck"
......@@ -574,7 +574,7 @@ ubuntu_gcc:
ubuntu_clang:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-dev
variables:
TASK_ID: "ubuntu-x86_64-clang-default-default-distcheck"
CC: clang
......@@ -587,7 +587,7 @@ lts:
<<: *build
<<: *jhbuild
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.ubuntu-lts
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.ubuntu-lts
variables:
TASK_ID: "ubuntu_lts-x86_64-gcc-default-default-check"
DEV: jhbuild
......@@ -599,7 +599,7 @@ lts:
valgrind:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-default-default-valgrind_check"
BUILD_OPTS: "--enable-valgrind --disable-valgrind-helgrind --prefix=/usr"
......@@ -634,7 +634,7 @@ flatpak:
zeal_2:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-debug-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-debug-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-debug-default-check_zeal2"
TEST: "check"
......@@ -646,7 +646,7 @@ zeal_2:
zeal_4:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-debug-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-debug-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-debug-default-check_zeal4"
TEST: "check"
......@@ -658,7 +658,7 @@ zeal_4:
zeal_11:
<<: *build
stage: manual
image: registry.gitlab.gnome.org/gnome/gjs:SM52-debug-gcc.fedora-dev
image: registry.gitlab.gnome.org/gnome/gjs:SM60-debug-gcc.fedora-dev
variables:
TASK_ID: "fedora-x86_64-gcc-debug-default-check_zeal11"
TEST: "check"
......@@ -674,7 +674,7 @@ armv8:
variables:
TASK_ID: "fedora-armv8-gcc-default-default-check"
DOCKER_DRIVER: overlay
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev.aarch64"
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev.aarch64"
when: manual
except:
- schedules
......@@ -685,7 +685,7 @@ ppc64le:
variables:
TASK_ID: "fedora-ppc64le-gcc-default-default-check"
DOCKER_DRIVER: overlay
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM52-gcc.fedora-dev.ppc64le"
IMAGE: "registry.gitlab.gnome.org/gnome/gjs:SM60-gcc.fedora-dev.ppc64le"
when: manual
except:
- schedules
......
......@@ -204,6 +204,7 @@ common_jstests_files = \
installed-tests/js/testGio.js \
installed-tests/js/testImporter.js \
installed-tests/js/testLang.js \
installed-tests/js/testLegacyByteArray.js \
installed-tests/js/testLegacyClass.js \
installed-tests/js/testLegacyGObject.js \
installed-tests/js/testLocale.js \
......
NEXT
----
- GJS now depends on SpiderMonkey 60 and requires a compiler capable of C++14.
- New JavaScript features! This version of GJS is based on SpiderMonkey 60, an
upgrade from the previous ESR (Extended Support Release) of SpiderMonkey 52.
Here are the highlights of the new JavaScript features.
For more information, look them up on MDN or devdocs.io.
* New syntax
+ `for await (... of ...)` syntax is used for async iteration.
+ The rest operator is now supported in object destructuring: e.g.
`({a, b, ...cd} = {a: 1, b: 2, c: 3, d: 4});`
+ The spread operator is now supported in object literals: e.g.
`mergedObject = {...obj1, ...obj2};`
+ Generator methods can now be async, using the `async function*` syntax,
or `async* f() {...}` method shorthand.
+ It's now allowed to omit the variable binding from a catch statement, if
you don't need to access the thrown exception: `try {...} catch {}`
* New APIs
+ Promise.prototype.finally(), popular in many third-party Promise
libraries, is now available natively.
+ String.prototype.toLocaleLowerCase() and
String.prototype.toLocaleUpperCase() now take an optional locale or
array of locales.
+ Intl.PluralRules is now available.
+ Intl.NumberFormat.protoype.formatToParts() is now available.
+ Intl.Collator now has a caseFirst option.
+ Intl.DateTimeFormat now has an hourCycle option.
* New behaviour
+ There are a lot of minor behaviour changes as SpiderMonkey's JS
implementation conforms ever closer to ECMAScript standards. For complete
information, read the Firefox developer release notes:
https://developer.mozilla.org/en-US/Firefox/Releases/53#JavaScript
https://developer.mozilla.org/en-US/Firefox/Releases/54#JavaScript
https://developer.mozilla.org/en-US/Firefox/Releases/55#JavaScript
https://developer.mozilla.org/en-US/Firefox/Releases/56#JavaScript
https://developer.mozilla.org/en-US/Firefox/Releases/57#JavaScript
https://developer.mozilla.org/en-US/Firefox/Releases/58#JavaScript
https://developer.mozilla.org/en-US/Firefox/Releases/59#JavaScript
https://developer.mozilla.org/en-US/Firefox/Releases/60#JavaScript
* Backwards-incompatible changes
+ Conditional catch clauses have been removed, as they were a Mozilla
extension which will not be standardized. This requires some attention in
GJS programs, as previously we condoned code like `catch (e if
e.matches(Gio.IOError, Gio.IOError.EXISTS))` with a comment in
overrides/GLib.js, so it's likely this is used in several places.
+ The nonstandard `for each (... in ...)` loop was removed.
+ The nonstandard legacy lambda syntax (`function(x) x*x`) was removed.
+ The nonstandard Mozilla iteration protocol was removed, as well as
nonstandard Mozilla generators, including the Iterator and StopIteration
objects, and the Function.prototype.isGenerator() method.
+ Array comprehensions and generator comprehensions have been removed.
+ Several nonstandard methods were removed: ArrayBuffer.slice() (but not
the standard version, ArrayBuffer.prototype.slice()),
Date.prototype.toLocaleFormat(), Function.prototype.isGenerator(),
Object.prototype.watch(), and Object.prototype.unwatch().
- Many of the above backwards-incompatible changes can be caught by scanning
your source code using https://gitlab.gnome.org/ptomato/moz60tool, or
https://extensions.gnome.org/extension/1455/spidermonkey-60-migration-validator/
- Deprecation: the custom ByteArray is now discouraged. Instead of ByteArray,
use Javascript's native Uint8Array. The ByteArray module still contains
functions for converting between byte arrays, strings, and GLib.Bytes
instances.
The old ByteArray will continue to work as before, except that Uint8Array
will now be returned from introspected functions that previously returned a
ByteArray. To keep your old code working, change this:
let byteArray = functionThatReturnsByteArray();
to this:
let byteArray = new ByteArray.ByteArray(functionThatReturnsByteArray());
To port to the new code:
* ByteArray.ByteArray -> Uint8Array
* ByteArray.fromArray() -> Uint8Array.from()
* ByteArray.ByteArray.prototype.toString() -> ByteArray.toString()
* ByteArray.ByteArray.prototype.toGBytes() -> ByteArray.toGBytes()
* ByteArray.fromString(), ByteArray.fromGBytes() remain the same
* Unlike ByteArray, Uint8Array's length is fixed. Assigning an element past
the end of a ByteArray would lengthen the array. Now, it is ignored.
Instead use Uint8Array.of(), for example, this code:
let a = ByteArray.fromArray([97, 98, 99, 100]);
a[4] = 101;
should be replaced by this code:
let a = Uint8Array.from([97, 98, 99, 100]);
a = Uint8Array.of(...a, 101);
The length of the byte array must be set at creation time. This code will
not work anymore:
let a = new ByteArray.ByteArray();
a[0] = 255;
Instead, use "new Uint8Array(1)" to reserve the correct length.
Version 1.53.4
--------------
......
......@@ -32,7 +32,7 @@ PKG_INSTALLDIR
AC_LANG([C++])
AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX_11
AX_CXX_COMPILE_STDCXX_14
LT_PREREQ([2.2.0])
# no stupid static libraries
......@@ -65,7 +65,7 @@ GOBJECT_INTROSPECTION_REQUIRE([1.41.4])
GOBJECT_REQUIREMENT="gobject-2.0 >= glib_required_version"
gjs_base_packages="$GOBJECT_REQUIREMENT gio-2.0"
common_packages="gthread-2.0 gio-2.0 >= glib_required_version mozjs-52"
common_packages="gthread-2.0 gio-2.0 >= glib_required_version mozjs-60"
gjs_packages="gobject-introspection-1.0 libffi $common_packages"
gjs_cairo_packages="cairo cairo-gobject $common_packages"
gjs_gtk_packages="gtk+-3.0 >= 3.20"
......
The ByteArray type in the `imports.byteArray` module is based on an
ECMAScript 4 proposal that was never adopted. This can be found at:
http://wiki.ecmascript.org/doku.php?id=proposals:bytearray
and the wikitext of that page is appended to this file.
The `imports.byteArray` module was originally based on an
ECMAScript 4 proposal that was never adopted.
Now that ES6 has typed arrays, we use `Uint8Array` to represent byte
arrays in GJS and add some extra functions for conversion to and from
strings and `GLib.Bytes`.
The main difference from the ECMA proposal is that gjs's ByteArray is
inside a module, and `toString()`/`fromString()` default to UTF-8 and take
optional encoding arguments.
There are a number of more elaborate byte array proposals in the
Common JS project at http://wiki.commonjs.org/wiki/Binary
We went with the ECMA proposal because it seems simplest, and the main
Unlike the old custom `ByteArray`, `Uint8Array` is not resizable. The main
goal for most gjs users will be to shovel bytes between various C
APIs, for example reading from an IO stream and then pushing the bytes
into a parser. Actually manipulating bytes in JS is likely to be
......@@ -20,138 +14,30 @@ messing with bytes, can be done in C.
---
ECMAScript proposal follows; remember it's almost but not quite like
gjs ByteArray, in particular we use UTF-8 instead of busted Latin-1 as
default encoding.
---
# ByteArray #
(Also see the [discussion page][1] for this proposal)
## Overview ##
In previous versions of ECMAScript, there wasn't a good way to efficiently represent a packed array of arbitrary bytes. The predefined core object Array is inefficient for this purpose; some developers have (mis)used character strings for this purpose, which may be slightly more efficient for some implementations, but still a misuse of the string type and either a less efficient use of memory (if one byte per character was stored) or cycles (if two bytes per char).
Edition 4 will add a new predefined core object, ByteArray. A ByteArray can be thought of as similar to an Array of uint ([uint]) with each element truncated to the integer range of 0..255.
## Creating a ByteArray ##
To create a ByteArray object:
```js
byteArrayObject = new ByteArray(byteArrayLength:uint)
```
byteArrayLength is the initial length of the ByteArray, in bytes. If omitted, the initial length is zero.
All elements in a ByteArray are initialized to the value of zero.
Unlike Array, there is no special form that allows you to list the initial values for the ByteArray's elements. However, the ByteArray class has an `intrinsic::to` static method that can convert an Array to a ByteArray, and implementations are free to optimize away the Array instance if it is used exclusively to initialize a ByteArray:
```js
var values:ByteArray = [1, 2, 3, 4]; // legal by virtue of ByteArray.intrinsic::to
```
## Populating a ByteArray ##
You can populate a ByteArray by assigning values to its elements. Each element can hold only an unsigned integer in the range 0..255 (inclusive). Values will be converted to unsigned integer (if necessary), then truncated to the least-significant 8 bits.
For example,
```js
var e = new ByteArray(3);
e[0] = 0x12; // stores 18
e[1] = Math.PI; // stores 3
e[2] = "foo"; // stores 0 (generates compile error in strict mode)
e[2] = "42"; // stores 42 (generates compile error in strict mode)
e[2] = null; // stores 0
e[2] = undefined; // stores 0
```
## Referring to ByteArray Elements ##
You refer to a ByteArray's elements by using the element's ordinal number; you refer to the first element of the array as `myArray[0]` and the second element of the array as `myArray[1]`, etc. The index of the elements begins with zero (0), but the length of array (for example, `myArray.length`) reflects the number of elements in the array.
## ByteArray Methods ##
The ByteArray object has the follow methods:
### `static function fromString(s:String):ByteArray` ###
Convert a String into newly constructed ByteArray; this creates a new ByteArray of the same length as the String, then assigns each ByteArray entry the corresponding charCodeAt() value of the String. As with other ByteArray assignments, only the lower 8 bits of the charCode value will be retained.
```js
class ByteArray {
...
static function fromString(s:String):ByteArray
{
var a:ByteArray = new Bytearray(s.length);
for (var i:int = 0; i < s.length; ++i)
a[i] = s.charCodeAt(i);
return a;
}
...
}
```
### `static function fromArray(s:Array):ByteArray` ###
Converts an Array into a newly constructed ByteArray; this creates a new ByteArray of the same length as the input Array, then assigns each ByteArray entry the corresponding entry value of the Array. As with other ByteArray assignments, only the lower 8 bits of the charCode value will be retained.
```js
class ByteArray {
...
static function fromArray(s:Array):ByteArray
{
var a:ByteArray = new Bytearray(s.length);
for (var i:int = 0; i < s.length; ++i)
a[i] = s[i];
return a;
...
}
```
### `function toString():String` ###
Converts the ByteArray into a literal string, with each character entry set to the value of the corresponding ByteArray entry.
The resulting string is guaranteed to round-trip back into an identical ByteArray by passing the result to `ByteArray.fromString()`, i.e., `b === ByteArray.fromString(b.toString())`. (Note that the reverse is not guaranteed to be true: `ByteArray.fromString(s).toString != s` unless all character codes in `s` are <= 255)
```js
class ByteArray {
...
function toString():String
{
// XXX return String.fromCharCode.apply(String, this);
var s:String = "";
for (var i:int = 0; i < this.length; ++i)
s += String.fromCharCode(this[i]);
return s;
}
...
}
```
## ByteArray Functions ##
## ByteArray Properties ##
The ByteArray module has the following functions:
The ByteArray object has the following properties:
### `fromString(s:String, encoding:String):Uint8Array` ###
### `length:uint` ###
Convert a String into a newly constructed `Uint8Array`; this creates a
new `Uint8Array` of the same length as the String, then assigns each
`Uint8Array` entry the corresponding byte value of the String encoded
according to the given encoding (or UTF-8 if not given).
This property contains the number of bytes in the ByteArray. Setting the length property to a smaller value decreases the size of the ByteArray, discarding the unused bytes. Setting the length property to a larger value increases the size of the ByteArray, initializing all newly-allocated elements to zero.
### `toString(a:Uint8Array, encoding:String):String` ###
### `prototype:Object` ###
Converts the `Uint8Array` into a literal string. The bytes are
interpreted according to the given encoding (or UTF-8 if not given).
This property contains the methods of ByteArray.
The resulting string is guaranteed to round-trip back into an identical ByteArray by passing the result to `ByteArray.fromString()`, i.e., `b === ByteArray.fromString(ByteArray.toString(b, encoding), encoding)`.
## Prior Art ##
### `fromGBytes(b:GLib.Bytes):Uint8Array` ###
Adobe's ActionScript 3.0 provides [`flash.utils.ByteArray`][2], which was the primary inspiration for this proposal. Note that the ActionScript version of ByteArray includes additional functionality which has been omitted here for the sake of allowing small implementations; it is anticipated that the extra functionality can be written in ES4 itself and provided as a standard library.
Convert a `GLib.Bytes` instance into a newly constructed `Uint8Array`.
The contents are copied.
[Synopsis of ActionScript's implementation too detailed and moved to [discussion][1] page]
### `toGBytes(a:Uint8Array):GLib.Bytes` ###
[1] http://wiki.ecmascript.org/doku.php?id=discussion:bytearray
[2] http://livedocs.macromedia.com/flex/2/langref/flash/utils/ByteArray.html
Converts the `Uint8Array` into a `GLib.Bytes` instance.
The contents are copied.
......@@ -19,10 +19,10 @@ Even if your system includes a development package for mozjs, we
recommend building it on JHBuild so that you can enable the debugging
features. Add this to your JHBuild configuration file:
```python
module_autogenargs['mozjs52'] = '--enable-debug'
module_autogenargs['mozjs60'] = '--enable-debug'
```
Make sure it is built first with `jhbuild build mozjs52`, otherwise
Make sure it is built first with `jhbuild build mozjs60`, otherwise
`jhbuild build gjs` will skip it if you have the system package
installed.
......@@ -46,7 +46,7 @@ mozjs, but you can grab them from your JHBuild copy of mozjs.
After reaching a breakpoint in your program, type this to activate the
pretty-printers:
```
source ~/.cache/jhbuild/build/mozjs-52.Y.Z/js/src/shell/js-gdb.py
source ~/.cache/jhbuild/build/mozjs-60.Y.Z/js/src/shell/js-gdb.py
```
(replace `Y.Z` with mozjs's minor and micro version numbers)
......
......@@ -1666,10 +1666,9 @@ gjs_value_to_g_argument(JSContext *context,
/* Handle Struct/Union first since we don't necessarily need a GType for them */
/* We special case Closures later, so skip them here */
!g_type_is_a(gtype, G_TYPE_CLOSURE)) {
if (g_type_is_a(gtype, G_TYPE_BYTES)
&& gjs_typecheck_bytearray(context, obj, false)) {
arg->v_pointer = gjs_byte_array_get_bytes(context, obj);
if (g_type_is_a(gtype, G_TYPE_BYTES) &&
JS_IsUint8Array(obj)) {
arg->v_pointer = gjs_byte_array_get_bytes(obj);
} else if (g_type_is_a(gtype, G_TYPE_ERROR)) {
if (!gjs_typecheck_gerror(context, obj, true)) {
arg->v_pointer = NULL;
......@@ -1955,13 +1954,13 @@ _Pragma("GCC diagnostic pop")
GIArrayType array_type = g_type_info_get_array_type(type_info);
/* First, let's handle the case where we're passed an instance
* of our own byteArray class.
* of Uint8Array and it needs to be marshalled to GByteArray.
*/
if (value.isObjectOrNull()) {
JS::RootedObject bytearray_obj(context, value.toObjectOrNull());
if (gjs_typecheck_bytearray(context, bytearray_obj, false)
&& array_type == GI_ARRAY_TYPE_BYTE_ARRAY) {
arg->v_pointer = gjs_byte_array_get_byte_array(context, bytearray_obj);
if (JS_IsUint8Array(bytearray_obj) &&
array_type == GI_ARRAY_TYPE_BYTE_ARRAY) {
arg->v_pointer = gjs_byte_array_get_byte_array(bytearray_obj);
break;
} else {
/* Fall through, !handled */
......@@ -2273,13 +2272,7 @@ gjs_array_from_carray_internal (JSContext *context,
/* Special case array(guint8) */
if (element_type == GI_TYPE_TAG_UINT8) {
GByteArray gbytearray;
gbytearray.data = (guint8 *) array;
gbytearray.len = length;
JS::RootedObject obj(context,
gjs_byte_array_from_byte_array(context, &gbytearray));
JSObject* obj = gjs_byte_array_from_data(context, length, array);
if (!obj)
return false;
value_p.setObject(*obj);
......@@ -2487,13 +2480,8 @@ gjs_array_from_zero_terminated_c_array (JSContext *context,
/* Special case array(guint8) */
if (element_type == GI_TYPE_TAG_UINT8) {
GByteArray gbytearray;
gbytearray.data = (guint8 *) c_array;
gbytearray.len = strlen((const char *) c_array);
JS::RootedObject obj(context,
gjs_byte_array_from_byte_array(context, &gbytearray));
size_t len = strlen(static_cast<char*>(c_array));
JSObject* obj = gjs_byte_array_from_data(context, len, c_array);
if (!obj)
return false;
value_p.setObject(*obj);
......@@ -3004,10 +2992,12 @@ gjs_value_from_g_argument (JSContext *context,
return gjs_array_from_fixed_size_array(context, value_p, type_info, arg->v_pointer);
}
} else if (g_type_info_get_array_type(type_info) == GI_ARRAY_TYPE_BYTE_ARRAY) {
JSObject *array = gjs_byte_array_from_byte_array(context,
(GByteArray*)arg->v_pointer);
auto* byte_array = static_cast<GByteArray*>(arg->v_pointer);
JSObject* array =
gjs_byte_array_from_byte_array(context, byte_array);
if (!array) {
gjs_throw(context, "Couldn't convert GByteArray to a ByteArray");
gjs_throw(context,
"Couldn't convert GByteArray to a Uint8Array");
return false;
}
value_p.setObject(*array);
......
......@@ -855,19 +855,17 @@ boxed_trace(JSTracer *tracer,
* class have.
*/
static const struct JSClassOps gjs_boxed_class_ops = {