tc39_test.go 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. package goja
  2. import (
  3. "errors"
  4. "fmt"
  5. "gopkg.in/yaml.v2"
  6. "io/ioutil"
  7. "os"
  8. "path"
  9. "sort"
  10. "strings"
  11. "sync"
  12. "testing"
  13. "time"
  14. )
  15. const (
  16. tc39BASE = "testdata/test262"
  17. )
  18. var (
  19. invalidFormatError = errors.New("Invalid file format")
  20. ignorableTestError = newSymbol(stringEmpty)
  21. sabStub = MustCompile("sabStub.js", `
  22. Object.defineProperty(this, "SharedArrayBuffer", {
  23. get: function() {
  24. throw IgnorableTestError;
  25. }
  26. });`,
  27. false)
  28. )
  29. var (
  30. skipList = map[string]bool{
  31. // Obsolete tests (see https://github.com/tc39/test262/pull/2445)
  32. //TODO: remove this after upgrading the test suite past the above PR
  33. "test/language/statements/function/scope-param-rest-elem-var-open.js": true,
  34. "test/language/statements/function/scope-param-rest-elem-var-close.js": true,
  35. "test/language/statements/function/scope-param-elem-var-open.js": true,
  36. "test/language/function-code/eval-param-env-with-prop-initializer.js": true,
  37. "test/language/function-code/eval-param-env-with-computed-key.js": true,
  38. "test/language/expressions/object/scope-meth-param-rest-elem-var-open.js": true,
  39. "test/language/statements/function/scope-param-elem-var-close.js": true,
  40. "test/language/expressions/object/scope-meth-param-rest-elem-var-close.js": true,
  41. "test/language/expressions/object/scope-meth-param-elem-var-open.js": true,
  42. "test/language/expressions/object/scope-meth-param-elem-var-close.js": true,
  43. "test/language/expressions/function/scope-param-rest-elem-var-open.js": true,
  44. "test/language/expressions/function/scope-param-rest-elem-var-close.js": true,
  45. "test/language/expressions/function/scope-param-elem-var-open.js": true,
  46. "test/language/expressions/function/scope-param-elem-var-close.js": true,
  47. "test/language/expressions/arrow-function/scope-param-rest-elem-var-open.js": true,
  48. "test/language/expressions/arrow-function/scope-param-rest-elem-var-close.js": true,
  49. "test/language/expressions/arrow-function/scope-param-elem-var-close.js": true,
  50. "test/language/expressions/arrow-function/scope-param-elem-var-open.js": true,
  51. "test/language/function-code/each-param-has-own-scope.js": true,
  52. "test/language/function-code/each-param-has-own-non-shared-eval-scope.js": true,
  53. // These tests are out of date (fixed in https://github.com/tc39/test262/commit/7d998a098e5420cb4b6ee4a05eb8c386d750c596)
  54. "test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-numericindex.js": true,
  55. "test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/key-is-numericindex-desc-configurable.js": true,
  56. // Fixed in https://github.com/tc39/test262/commit/7d998a098e5420cb4b6ee4a05eb8c386d750c596
  57. "test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer.js": true,
  58. // Fixed in https://github.com/tc39/test262/commit/0bb8fe8aba97765aa3a8d4dd8880cd8e3c238f68
  59. "test/built-ins/TypedArrayConstructors/internals/Get/detached-buffer.js": true,
  60. "test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/tonumber-value-detached-buffer.js": true,
  61. // 36c2cd165f93e194b9bcad26e69e8571b1d0e6ed
  62. "test/built-ins/ArrayBuffer/prototype/byteLength/detached-buffer.js": true,
  63. // 96aff62fb25cf9ef27929a8ab822ee853d99b06e
  64. "test/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-detached-buffer.js": true,
  65. "test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds.js": true,
  66. // 167e596a649ede35df11d03cb3c093941c9cf396
  67. "test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer.js": true,
  68. // Anonymous function name property (now always present)
  69. "test/language/expressions/function/name.js": true,
  70. "test/built-ins/Proxy/revocable/revocation-function-name.js": true,
  71. "test/built-ins/Promise/all/resolve-element-function-name.js": true,
  72. "test/built-ins/Promise/allSettled/resolve-element-function-name.js": true,
  73. "test/built-ins/Promise/allSettled/reject-element-function-name.js": true,
  74. "test/built-ins/Promise/resolve-function-name.js": true,
  75. "test/built-ins/Promise/reject-function-name.js": true,
  76. // obsolete tests (to remove)
  77. "test/built-ins/Promise/race/invoke-resolve-get-error-close.js": true,
  78. "test/built-ins/Promise/allSettled/invoke-resolve-get-error-close.js": true,
  79. "test/built-ins/Promise/all/invoke-resolve-get-error-close.js": true,
  80. // timezone
  81. "test/built-ins/Date/prototype/toISOString/15.9.5.43-0-8.js": true,
  82. "test/built-ins/Date/prototype/toISOString/15.9.5.43-0-9.js": true,
  83. "test/built-ins/Date/prototype/toISOString/15.9.5.43-0-10.js": true,
  84. // SharedArrayBuffer
  85. "test/built-ins/ArrayBuffer/prototype/slice/this-is-sharedarraybuffer.js": true,
  86. // class
  87. "test/language/statements/class/subclass/builtin-objects/Symbol/symbol-valid-as-extends-value.js": true,
  88. "test/language/statements/class/subclass/builtin-objects/Symbol/new-symbol-with-super-throws.js": true,
  89. "test/language/statements/class/subclass/builtin-objects/WeakSet/super-must-be-called.js": true,
  90. "test/language/statements/class/subclass/builtin-objects/WeakSet/regular-subclassing.js": true,
  91. "test/language/statements/class/subclass/builtin-objects/WeakMap/super-must-be-called.js": true,
  92. "test/language/statements/class/subclass/builtin-objects/WeakMap/regular-subclassing.js": true,
  93. "test/language/statements/class/subclass/builtin-objects/Map/super-must-be-called.js": true,
  94. "test/language/statements/class/subclass/builtin-objects/Map/regular-subclassing.js": true,
  95. "test/language/statements/class/subclass/builtin-objects/Set/super-must-be-called.js": true,
  96. "test/language/statements/class/subclass/builtin-objects/Set/regular-subclassing.js": true,
  97. "test/language/statements/class/subclass/builtin-objects/Object/replacing-prototype.js": true,
  98. "test/language/statements/class/subclass/builtin-objects/Object/regular-subclassing.js": true,
  99. "test/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js": true,
  100. "test/language/statements/class/subclass/builtin-objects/Array/length.js": true,
  101. "test/language/statements/class/subclass/builtin-objects/TypedArray/super-must-be-called.js": true,
  102. "test/language/statements/class/subclass/builtin-objects/TypedArray/regular-subclassing.js": true,
  103. "test/language/statements/class/subclass/builtin-objects/DataView/super-must-be-called.js": true,
  104. "test/language/statements/class/subclass/builtin-objects/DataView/regular-subclassing.js": true,
  105. "test/language/statements/class/subclass/builtin-objects/String/super-must-be-called.js": true,
  106. "test/language/statements/class/subclass/builtin-objects/String/regular-subclassing.js": true,
  107. "test/language/statements/class/subclass/builtin-objects/String/length.js": true,
  108. "test/language/statements/class/subclass/builtin-objects/Date/super-must-be-called.js": true,
  109. "test/language/statements/class/subclass/builtin-objects/Date/regular-subclassing.js": true,
  110. "test/language/statements/class/subclass/builtin-objects/Number/super-must-be-called.js": true,
  111. "test/language/statements/class/subclass/builtin-objects/Number/regular-subclassing.js": true,
  112. "test/language/statements/class/subclass/builtin-objects/Function/super-must-be-called.js": true,
  113. "test/language/statements/class/subclass/builtin-objects/Function/regular-subclassing.js": true,
  114. "test/language/statements/class/subclass/builtin-objects/Function/instance-name.js": true,
  115. "test/language/statements/class/subclass/builtin-objects/Function/instance-length.js": true,
  116. "test/language/statements/class/subclass/builtin-objects/Boolean/super-must-be-called.js": true,
  117. "test/language/statements/class/subclass/builtin-objects/Boolean/regular-subclassing.js": true,
  118. "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-super.js": true,
  119. "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-name.js": true,
  120. "test/language/statements/class/subclass/builtin-objects/NativeError/URIError-message.js": true,
  121. "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-super.js": true,
  122. "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-name.js": true,
  123. "test/language/statements/class/subclass/builtin-objects/NativeError/TypeError-message.js": true,
  124. "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-super.js": true,
  125. "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-name.js": true,
  126. "test/language/statements/class/subclass/builtin-objects/NativeError/SyntaxError-message.js": true,
  127. "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-super.js": true,
  128. "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-name.js": true,
  129. "test/language/statements/class/subclass/builtin-objects/NativeError/ReferenceError-message.js": true,
  130. "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-super.js": true,
  131. "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-name.js": true,
  132. "test/language/statements/class/subclass/builtin-objects/NativeError/RangeError-message.js": true,
  133. "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-super.js": true,
  134. "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-name.js": true,
  135. "test/language/statements/class/subclass/builtin-objects/NativeError/EvalError-message.js": true,
  136. "test/language/statements/class/subclass/builtin-objects/Error/super-must-be-called.js": true,
  137. "test/language/statements/class/subclass/builtin-objects/Error/regular-subclassing.js": true,
  138. "test/language/statements/class/subclass/builtin-objects/Error/message-property-assignment.js": true,
  139. "test/language/statements/class/subclass/builtin-objects/Array/super-must-be-called.js": true,
  140. "test/language/statements/class/subclass/builtin-objects/Array/regular-subclassing.js": true,
  141. "test/language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-single-argument.js": true,
  142. "test/language/statements/class/subclass/builtin-objects/Array/contructor-calls-super-multiple-arguments.js": true,
  143. "test/language/statements/class/subclass/builtin-objects/ArrayBuffer/super-must-be-called.js": true,
  144. "test/language/statements/class/subclass/builtin-objects/ArrayBuffer/regular-subclassing.js": true,
  145. "test/built-ins/ArrayBuffer/isView/arg-is-typedarray-subclass-instance.js": true,
  146. "test/built-ins/ArrayBuffer/isView/arg-is-dataview-subclass-instance.js": true,
  147. "test/language/statements/class/subclass/builtin-objects/RegExp/super-must-be-called.js": true,
  148. "test/language/statements/class/subclass/builtin-objects/RegExp/regular-subclassing.js": true,
  149. "test/language/statements/class/subclass/builtin-objects/RegExp/lastIndex.js": true,
  150. "TestTC39/tc39/test/language/statements/class/definition/fn-name-method.js": true,
  151. "test/language/expressions/object/method-definition/name-invoke-ctor.js": true,
  152. "test/language/expressions/object/method.js": true,
  153. "test/language/expressions/object/setter-super-prop.js": true,
  154. "test/language/expressions/object/getter-super-prop.js": true,
  155. "test/language/expressions/delete/super-property.js": true,
  156. "test/language/statements/let/dstr/obj-ptrn-id-init-fn-name-class.js": true,
  157. "test/language/statements/let/dstr/ary-ptrn-elem-id-init-fn-name-class.js": true,
  158. "test/language/statements/for/dstr/var-obj-ptrn-id-init-fn-name-class.js": true,
  159. "test/language/statements/for/dstr/var-ary-ptrn-elem-id-init-fn-name-class.js": true,
  160. "test/language/statements/for/dstr/let-ary-ptrn-elem-id-init-fn-name-class.js": true,
  161. "test/language/statements/for/dstr/let-obj-ptrn-id-init-fn-name-class.js": true,
  162. "test/language/statements/const/dstr/ary-ptrn-elem-id-init-fn-name-class.js": true,
  163. "test/language/statements/for/dstr/const-obj-ptrn-id-init-fn-name-class.js": true,
  164. "test/language/statements/const/dstr/obj-ptrn-id-init-fn-name-class.js": true,
  165. "test/language/statements/for/dstr/const-ary-ptrn-elem-id-init-fn-name-class.js": true,
  166. "test/language/statements/variable/dstr/obj-ptrn-id-init-fn-name-class.js": true,
  167. "test/language/statements/variable/dstr/ary-ptrn-elem-id-init-fn-name-class.js": true,
  168. "test/language/expressions/object/method-definition/name-name-prop-symbol.js": true,
  169. "test/language/expressions/function/dstr/dflt-obj-ptrn-id-init-fn-name-class.js": true,
  170. "test/language/expressions/function/dstr/dflt-ary-ptrn-elem-id-init-fn-name-class.js": true,
  171. "test/language/expressions/function/dstr/ary-ptrn-elem-id-init-fn-name-class.js": true,
  172. "test/language/expressions/function/dstr/obj-ptrn-id-init-fn-name-class.js": true,
  173. "test/language/statements/function/dstr/dflt-ary-ptrn-elem-id-init-fn-name-class.js": true,
  174. "test/language/statements/function/dstr/obj-ptrn-id-init-fn-name-class.js": true,
  175. "test/language/statements/function/dstr/ary-ptrn-elem-id-init-fn-name-class.js": true,
  176. "test/language/statements/function/dstr/dflt-obj-ptrn-id-init-fn-name-class.js": true,
  177. "test/language/statements/class/scope-static-setter-paramsbody-var-open.js": true,
  178. "test/language/statements/class/scope-static-setter-paramsbody-var-close.js": true,
  179. "test/language/statements/class/scope-static-meth-paramsbody-var-open.js": true,
  180. "test/language/statements/class/scope-static-meth-paramsbody-var-close.js": true,
  181. "test/language/statements/class/scope-setter-paramsbody-var-open.js": true,
  182. "test/language/statements/class/scope-setter-paramsbody-var-close.js": true,
  183. "test/language/statements/class/scope-meth-paramsbody-var-open.js": true,
  184. "test/language/statements/class/scope-meth-paramsbody-var-close.js": true,
  185. "test/language/expressions/class/scope-static-setter-paramsbody-var-open.js": true,
  186. "test/language/expressions/class/scope-static-setter-paramsbody-var-close.js": true,
  187. "test/language/expressions/class/scope-static-meth-paramsbody-var-open.js": true,
  188. "test/language/expressions/class/scope-static-meth-paramsbody-var-close.js": true,
  189. "test/language/expressions/class/scope-setter-paramsbody-var-open.js": true,
  190. "test/language/expressions/class/scope-setter-paramsbody-var-close.js": true,
  191. "test/language/expressions/class/scope-meth-paramsbody-var-open.js": true,
  192. "test/language/expressions/class/scope-meth-paramsbody-var-close.js": true,
  193. "test/language/expressions/arrow-function/scope-paramsbody-var-open.js": true,
  194. "test/language/expressions/arrow-function/scope-paramsbody-var-close.js": true,
  195. "test/language/expressions/arrow-function/scope-body-lex-distinct.js": true,
  196. "test/language/statements/for-of/dstr/var-ary-ptrn-elem-id-init-fn-name-class.js": true,
  197. "test/language/statements/for-of/dstr/var-obj-ptrn-id-init-fn-name-class.js": true,
  198. "test/language/statements/for-of/dstr/const-obj-ptrn-id-init-fn-name-class.js": true,
  199. "test/language/statements/for-of/dstr/let-obj-ptrn-id-init-fn-name-class.js": true,
  200. "test/language/statements/for-of/dstr/const-ary-ptrn-elem-id-init-fn-name-class.js": true,
  201. "test/language/statements/for-of/dstr/let-ary-ptrn-elem-id-init-fn-name-class.js": true,
  202. "test/language/statements/try/dstr/obj-ptrn-id-init-fn-name-class.js": true,
  203. "test/language/statements/try/dstr/ary-ptrn-elem-id-init-fn-name-class.js": true,
  204. "test/language/expressions/arrow-function/dstr/ary-ptrn-elem-id-init-fn-name-class.js": true,
  205. "test/language/expressions/arrow-function/dstr/dflt-obj-ptrn-id-init-fn-name-class.js": true,
  206. "test/language/expressions/arrow-function/dstr/obj-ptrn-id-init-fn-name-class.js": true,
  207. "test/language/expressions/arrow-function/dstr/dflt-ary-ptrn-elem-id-init-fn-name-class.js": true,
  208. "test/language/statements/class/static-method-length-dflt.js": true,
  209. "test/language/statements/class/setter-length-dflt.js": true,
  210. "test/language/statements/class/restricted-properties.js": true,
  211. "test/language/statements/class/method-length-dflt.js": true,
  212. "test/language/statements/class/definition/methods-restricted-properties.js": true,
  213. "test/language/expressions/class/static-method-length-dflt.js": true,
  214. "test/language/expressions/class/setter-length-dflt.js": true,
  215. "test/language/expressions/class/restricted-properties.js": true,
  216. "test/language/expressions/class/method-length-dflt.js": true,
  217. "test/language/expressions/arrow-function/lexical-super-property-from-within-constructor.js": true,
  218. "test/language/expressions/arrow-function/lexical-super-property.js": true,
  219. "test/language/expressions/arrow-function/lexical-supercall-from-immediately-invoked-arrow.js": true,
  220. "test/language/statements/class/subclass/builtin-objects/Promise/super-must-be-called.js": true,
  221. "test/language/statements/class/subclass/builtin-objects/Promise/regular-subclassing.js": true,
  222. "test/built-ins/Promise/prototype/finally/subclass-species-constructor-resolve-count.js": true,
  223. "test/built-ins/Promise/prototype/finally/subclass-species-constructor-reject-count.js": true,
  224. "test/built-ins/Promise/prototype/finally/subclass-resolve-count.js": true,
  225. "test/built-ins/Promise/prototype/finally/species-symbol.js": true,
  226. "test/built-ins/Promise/prototype/finally/subclass-reject-count.js": true,
  227. "test/built-ins/Promise/prototype/finally/species-constructor.js": true,
  228. // restricted unicode regexp syntax
  229. "test/built-ins/RegExp/unicode_restricted_quantifiable_assertion.js": true,
  230. "test/built-ins/RegExp/unicode_restricted_octal_escape.js": true,
  231. "test/built-ins/RegExp/unicode_restricted_incomple_quantifier.js": true,
  232. "test/built-ins/RegExp/unicode_restricted_incomplete_quantifier.js": true,
  233. "test/built-ins/RegExp/unicode_restricted_identity_escape_x.js": true,
  234. "test/built-ins/RegExp/unicode_restricted_identity_escape_u.js": true,
  235. "test/built-ins/RegExp/unicode_restricted_identity_escape_c.js": true,
  236. "test/built-ins/RegExp/unicode_restricted_identity_escape_alpha.js": true,
  237. "test/built-ins/RegExp/unicode_restricted_identity_escape.js": true,
  238. "test/built-ins/RegExp/unicode_restricted_brackets.js": true,
  239. "test/built-ins/RegExp/unicode_restricted_character_class_escape.js": true,
  240. "test/annexB/built-ins/RegExp/prototype/compile/pattern-string-invalid-u.js": true,
  241. // regexp named groups
  242. "test/built-ins/RegExp/prototype/Symbol.replace/named-groups-fn.js": true,
  243. "test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-groups-err.js": true,
  244. "test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-groups-prop-err.js": true,
  245. "test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-groups-prop.js": true,
  246. "test/built-ins/RegExp/prototype/Symbol.replace/result-coerce-groups.js": true,
  247. "test/built-ins/RegExp/prototype/Symbol.replace/result-get-groups-err.js": true,
  248. "test/built-ins/RegExp/prototype/Symbol.replace/result-get-groups-prop-err.js": true,
  249. "test/built-ins/RegExp/named-groups/functional-replace-non-global.js": true,
  250. "test/built-ins/RegExp/named-groups/functional-replace-global.js": true,
  251. // Because goja parser works in UTF-8 it is not possible to pass strings containing invalid UTF-16 code points.
  252. // This is mitigated by escaping them as \uXXXX, however because of this the RegExp source becomes
  253. // `\uXXXX` instead of `<the actual UTF-16 code point of XXXX>`.
  254. // The resulting RegExp will work exactly the same, but it causes these two tests to fail.
  255. "test/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js": true,
  256. "test/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js": true,
  257. // Promise
  258. "test/built-ins/Symbol/species/builtin-getter-name.js": true,
  259. // x ** y
  260. "test/built-ins/Array/prototype/pop/clamps-to-integer-limit.js": true,
  261. "test/built-ins/Array/prototype/pop/length-near-integer-limit.js": true,
  262. "test/built-ins/Array/prototype/push/clamps-to-integer-limit.js": true,
  263. "test/built-ins/Array/prototype/push/length-near-integer-limit.js": true,
  264. "test/built-ins/Array/prototype/push/throws-if-integer-limit-exceeded.js": true,
  265. "test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-object.js": true,
  266. "test/built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-proxy.js": true,
  267. "test/built-ins/Array/prototype/slice/length-exceeding-integer-limit.js": true,
  268. "test/built-ins/Array/prototype/splice/clamps-length-to-integer-limit.js": true,
  269. "test/built-ins/Array/prototype/splice/length-and-deleteCount-exceeding-integer-limit.js": true,
  270. "test/built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array.js": true,
  271. "test/built-ins/Array/prototype/splice/length-near-integer-limit-grow-array.js": true,
  272. "test/built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded.js": true,
  273. "test/built-ins/Array/prototype/unshift/clamps-to-integer-limit.js": true,
  274. "test/built-ins/Array/prototype/unshift/length-near-integer-limit.js": true,
  275. "test/built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded.js": true,
  276. "test/built-ins/String/prototype/split/separator-undef-limit-custom.js": true,
  277. "test/built-ins/Array/prototype/splice/create-species-length-exceeding-integer-limit.js": true,
  278. "test/built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array.js": true,
  279. "test/built-ins/String/prototype/split/separator-undef-limit-zero.js": true,
  280. // generators
  281. "test/annexB/built-ins/RegExp/RegExp-control-escape-russian-letter.js": true,
  282. "test/language/statements/switch/scope-lex-generator.js": true,
  283. // async
  284. "test/language/eval-code/direct/async-func-decl-a-preceding-parameter-is-named-arguments-declare-arguments-and-assign.js": true,
  285. }
  286. featuresBlackList = []string{
  287. "async-iteration",
  288. "BigInt",
  289. "class",
  290. "generators",
  291. "String.prototype.replaceAll",
  292. "String.prototype.at",
  293. "super",
  294. "resizable-arraybuffer",
  295. "array-find-from-last",
  296. "Array.prototype.at",
  297. "TypedArray.prototype.at",
  298. }
  299. es6WhiteList = map[string]bool{}
  300. es6IdWhiteList = []string{
  301. "8.1.2.1",
  302. "9.5",
  303. "11.8.3",
  304. "11.8.6",
  305. "12.1",
  306. "12.2.1",
  307. "12.2.2",
  308. "12.2.5",
  309. "12.2.6.1",
  310. "12.2.6.8",
  311. "12.2.8",
  312. "12.2.9",
  313. "12.3.7",
  314. "12.4",
  315. "12.5",
  316. "12.6",
  317. "12.7",
  318. "12.8",
  319. "12.9",
  320. "12.10",
  321. "13.1",
  322. "13.2",
  323. "13.3",
  324. "13.4",
  325. "13.5",
  326. "13.6",
  327. "13.7",
  328. "13.8",
  329. "13.9",
  330. "13.10",
  331. "13.11",
  332. "13.12",
  333. "13.13",
  334. "13.14",
  335. "13.15",
  336. "14.1",
  337. "14.2",
  338. "14.3.8",
  339. "16.1",
  340. "18",
  341. "19",
  342. "20",
  343. "21",
  344. "22",
  345. "23",
  346. "24",
  347. "25.1",
  348. "25.4",
  349. "26",
  350. "B.2.1",
  351. "B.2.2",
  352. }
  353. esIdPrefixWhiteList = []string{
  354. "sec-addition-*",
  355. "sec-array",
  356. "sec-%typedarray%",
  357. "sec-%typedarray%-of",
  358. "sec-@@iterator",
  359. "sec-@@tostringtag",
  360. "sec-string",
  361. "sec-date",
  362. "sec-json",
  363. "sec-number",
  364. "sec-math",
  365. "sec-arraybuffer-length",
  366. "sec-arraybuffer",
  367. "sec-regexp",
  368. "sec-string.prototype.trimLeft",
  369. "sec-string.prototype.trimRight",
  370. "sec-object.getownpropertydescriptor",
  371. "sec-object.getownpropertydescriptors",
  372. "sec-object.entries",
  373. "sec-object.values",
  374. "sec-object-initializer",
  375. "sec-proxy-*",
  376. "sec-for-statement-*",
  377. "sec-for-in-and-for-of-statements",
  378. "sec-for-in-and-for-of-statements-*",
  379. "sec-do-while-statement",
  380. "sec-if-statement",
  381. "sec-while-statement",
  382. "sec-with-statement*",
  383. "sec-switch-*",
  384. "sec-try-*",
  385. "sec-runtime-semantics-catchclauseevaluation",
  386. "sec-strict-mode-of-ecmascript",
  387. "sec-let-and-const-declarations*",
  388. "sec-arguments-exotic-objects-defineownproperty-p-desc",
  389. "sec-other-properties-of-the-global-object-globalthis",
  390. "sec-variable-statement-runtime-semantics-evaluation",
  391. "sec-function-calls-runtime-semantics-evaluation",
  392. "sec-function-definitions",
  393. "sec-function-definitions-runtime-semantics-evaluation",
  394. "sec-function-definitions-runtime-semantics-instantiatefunctionobject",
  395. "sec-function-definitions-runtime-semantics-iteratorbindinginitialization",
  396. "sec-function-definitions-static-semantics-early-errors",
  397. "sec-functiondeclarationinstantiation",
  398. "sec-functiondeclarations-in-ifstatement-statement-clauses",
  399. "sec-arrow-function-definitions",
  400. "sec-arrow-function-definitions-runtime-semantics-evaluation",
  401. "sec-arrow-function-definitions-static-semantics-early-errors",
  402. "sec-evaldeclarationinstantiation",
  403. "sec-integer-indexed-exotic-objects-defineownproperty-p-desc",
  404. "sec-integer-indexed-exotic-objects-get-p-receiver",
  405. "sec-integer-indexed-exotic-objects-set-p-v-receiver",
  406. "sec-destructuring-binding-patterns",
  407. "sec-runtime-semantics-keyeddestructuringassignmentevaluation",
  408. "sec-gettemplateobject",
  409. "sec-tagged-templates-runtime-semantics-evaluation",
  410. "sec-template-literal-lexical-components",
  411. "sec-template-literals",
  412. "sec-literals-numeric-literals",
  413. "sec-literals-string-literals",
  414. "sec-additional-syntax-numeric-literals",
  415. "sec-promise",
  416. "sec-promise-constructor",
  417. "sec-promise-executor",
  418. "sec-promise-reject-functions",
  419. "sec-promise-resolve-functions",
  420. "sec-performpromiseall",
  421. "sec-performpromiseallsettled",
  422. "sec-properties-of-the-promise-prototype-object",
  423. }
  424. )
  425. type tc39Test struct {
  426. name string
  427. f func(t *testing.T)
  428. }
  429. type tc39BenchmarkItem struct {
  430. name string
  431. duration time.Duration
  432. }
  433. type tc39BenchmarkData []tc39BenchmarkItem
  434. type tc39TestCtx struct {
  435. base string
  436. t *testing.T
  437. prgCache map[string]*Program
  438. prgCacheLock sync.Mutex
  439. enableBench bool
  440. benchmark tc39BenchmarkData
  441. benchLock sync.Mutex
  442. testQueue []tc39Test
  443. }
  444. type TC39MetaNegative struct {
  445. Phase, Type string
  446. }
  447. type tc39Meta struct {
  448. Negative TC39MetaNegative
  449. Includes []string
  450. Flags []string
  451. Features []string
  452. Es5id string
  453. Es6id string
  454. Esid string
  455. }
  456. func (m *tc39Meta) hasFlag(flag string) bool {
  457. for _, f := range m.Flags {
  458. if f == flag {
  459. return true
  460. }
  461. }
  462. return false
  463. }
  464. func parseTC39File(name string) (*tc39Meta, string, error) {
  465. f, err := os.Open(name)
  466. if err != nil {
  467. return nil, "", err
  468. }
  469. defer f.Close()
  470. b, err := ioutil.ReadAll(f)
  471. if err != nil {
  472. return nil, "", err
  473. }
  474. str := string(b)
  475. metaStart := strings.Index(str, "/*---")
  476. if metaStart == -1 {
  477. return nil, "", invalidFormatError
  478. } else {
  479. metaStart += 5
  480. }
  481. metaEnd := strings.Index(str, "---*/")
  482. if metaEnd == -1 || metaEnd <= metaStart {
  483. return nil, "", invalidFormatError
  484. }
  485. var meta tc39Meta
  486. err = yaml.Unmarshal([]byte(str[metaStart:metaEnd]), &meta)
  487. if err != nil {
  488. return nil, "", err
  489. }
  490. if meta.Negative.Type != "" && meta.Negative.Phase == "" {
  491. return nil, "", errors.New("negative type is set, but phase isn't")
  492. }
  493. return &meta, str, nil
  494. }
  495. func (*tc39TestCtx) detachArrayBuffer(call FunctionCall) Value {
  496. if obj, ok := call.Argument(0).(*Object); ok {
  497. if buf, ok := obj.self.(*arrayBufferObject); ok {
  498. buf.detach()
  499. return _undefined
  500. }
  501. }
  502. panic(typeError("detachArrayBuffer() is called with incompatible argument"))
  503. }
  504. func (*tc39TestCtx) throwIgnorableTestError(FunctionCall) Value {
  505. panic(ignorableTestError)
  506. }
  507. func (ctx *tc39TestCtx) runTC39Test(name, src string, meta *tc39Meta, t testing.TB) {
  508. defer func() {
  509. if x := recover(); x != nil {
  510. panic(fmt.Sprintf("panic while running %s: %v", name, x))
  511. }
  512. }()
  513. vm := New()
  514. _262 := vm.NewObject()
  515. _262.Set("detachArrayBuffer", ctx.detachArrayBuffer)
  516. _262.Set("createRealm", ctx.throwIgnorableTestError)
  517. vm.Set("$262", _262)
  518. vm.Set("IgnorableTestError", ignorableTestError)
  519. vm.RunProgram(sabStub)
  520. var out []string
  521. async := meta.hasFlag("async")
  522. if async {
  523. err := ctx.runFile(ctx.base, path.Join("harness", "doneprintHandle.js"), vm)
  524. if err != nil {
  525. t.Fatal(err)
  526. }
  527. vm.Set("print", func(msg string) {
  528. out = append(out, msg)
  529. })
  530. } else {
  531. vm.Set("print", t.Log)
  532. }
  533. err, early := ctx.runTC39Script(name, src, meta.Includes, vm)
  534. if err != nil {
  535. if meta.Negative.Type == "" {
  536. if err, ok := err.(*Exception); ok {
  537. if err.Value() == ignorableTestError {
  538. t.Skip("Test threw IgnorableTestError")
  539. }
  540. }
  541. t.Fatalf("%s: %v", name, err)
  542. } else {
  543. if (meta.Negative.Phase == "early" || meta.Negative.Phase == "parse") && !early || meta.Negative.Phase == "runtime" && early {
  544. t.Fatalf("%s: error %v happened at the wrong phase (expected %s)", name, err, meta.Negative.Phase)
  545. }
  546. var errType string
  547. switch err := err.(type) {
  548. case *Exception:
  549. if o, ok := err.Value().(*Object); ok {
  550. if c := o.Get("constructor"); c != nil {
  551. if c, ok := c.(*Object); ok {
  552. errType = c.Get("name").String()
  553. } else {
  554. t.Fatalf("%s: error constructor is not an object (%v)", name, o)
  555. }
  556. } else {
  557. t.Fatalf("%s: error does not have a constructor (%v)", name, o)
  558. }
  559. } else {
  560. t.Fatalf("%s: error is not an object (%v)", name, err.Value())
  561. }
  562. case *CompilerSyntaxError:
  563. errType = "SyntaxError"
  564. case *CompilerReferenceError:
  565. errType = "ReferenceError"
  566. default:
  567. t.Fatalf("%s: error is not a JS error: %v", name, err)
  568. }
  569. if errType != meta.Negative.Type {
  570. vm.vm.prg.dumpCode(t.Logf)
  571. t.Fatalf("%s: unexpected error type (%s), expected (%s)", name, errType, meta.Negative.Type)
  572. }
  573. }
  574. } else {
  575. if meta.Negative.Type != "" {
  576. vm.vm.prg.dumpCode(t.Logf)
  577. t.Fatalf("%s: Expected error: %v", name, err)
  578. }
  579. }
  580. if vm.vm.sp != 0 {
  581. t.Fatalf("sp: %d", vm.vm.sp)
  582. }
  583. if l := len(vm.vm.iterStack); l > 0 {
  584. t.Fatalf("iter stack is not empty: %d", l)
  585. }
  586. if async {
  587. complete := false
  588. for _, line := range out {
  589. if strings.HasPrefix(line, "Test262:AsyncTestFailure:") {
  590. t.Fatal(line)
  591. } else if line == "Test262:AsyncTestComplete" {
  592. complete = true
  593. }
  594. }
  595. if !complete {
  596. for _, line := range out {
  597. t.Log(line)
  598. }
  599. t.Fatal("Test262:AsyncTestComplete was not printed")
  600. }
  601. }
  602. }
  603. func (ctx *tc39TestCtx) runTC39File(name string, t testing.TB) {
  604. if skipList[name] {
  605. t.Skip("Excluded")
  606. }
  607. p := path.Join(ctx.base, name)
  608. meta, src, err := parseTC39File(p)
  609. if err != nil {
  610. //t.Fatalf("Could not parse %s: %v", name, err)
  611. t.Errorf("Could not parse %s: %v", name, err)
  612. return
  613. }
  614. if meta.Es5id == "" {
  615. skip := true
  616. //t.Logf("%s: Not ES5, skipped", name)
  617. if es6WhiteList[name] {
  618. skip = false
  619. } else {
  620. if meta.Es6id != "" {
  621. for _, prefix := range es6IdWhiteList {
  622. if strings.HasPrefix(meta.Es6id, prefix) &&
  623. (len(meta.Es6id) == len(prefix) || meta.Es6id[len(prefix)] == '.') {
  624. skip = false
  625. break
  626. }
  627. }
  628. }
  629. }
  630. if skip {
  631. if meta.Esid != "" {
  632. for _, prefix := range esIdPrefixWhiteList {
  633. if strings.HasSuffix(prefix, "*") {
  634. if strings.HasPrefix(meta.Esid, prefix[:len(prefix)-1]) {
  635. skip = false
  636. break
  637. }
  638. } else {
  639. if strings.HasPrefix(meta.Esid, prefix) &&
  640. (len(meta.Esid) == len(prefix) || meta.Esid[len(prefix)] == '.') {
  641. skip = false
  642. break
  643. }
  644. }
  645. }
  646. }
  647. }
  648. if skip {
  649. t.Skip("Not ES5")
  650. }
  651. for _, feature := range meta.Features {
  652. for _, bl := range featuresBlackList {
  653. if feature == bl {
  654. t.Skip("Blacklisted feature")
  655. }
  656. }
  657. }
  658. }
  659. var startTime time.Time
  660. if ctx.enableBench {
  661. startTime = time.Now()
  662. }
  663. hasRaw := meta.hasFlag("raw")
  664. if hasRaw || !meta.hasFlag("onlyStrict") {
  665. //log.Printf("Running normal test: %s", name)
  666. t.Logf("Running normal test: %s", name)
  667. ctx.runTC39Test(name, src, meta, t)
  668. }
  669. if !hasRaw && !meta.hasFlag("noStrict") {
  670. //log.Printf("Running strict test: %s", name)
  671. t.Logf("Running strict test: %s", name)
  672. ctx.runTC39Test(name, "'use strict';\n"+src, meta, t)
  673. }
  674. if ctx.enableBench {
  675. ctx.benchLock.Lock()
  676. ctx.benchmark = append(ctx.benchmark, tc39BenchmarkItem{
  677. name: name,
  678. duration: time.Since(startTime),
  679. })
  680. ctx.benchLock.Unlock()
  681. }
  682. }
  683. func (ctx *tc39TestCtx) init() {
  684. ctx.prgCache = make(map[string]*Program)
  685. }
  686. func (ctx *tc39TestCtx) compile(base, name string) (*Program, error) {
  687. ctx.prgCacheLock.Lock()
  688. defer ctx.prgCacheLock.Unlock()
  689. prg := ctx.prgCache[name]
  690. if prg == nil {
  691. fname := path.Join(base, name)
  692. f, err := os.Open(fname)
  693. if err != nil {
  694. return nil, err
  695. }
  696. defer f.Close()
  697. b, err := ioutil.ReadAll(f)
  698. if err != nil {
  699. return nil, err
  700. }
  701. str := string(b)
  702. prg, err = Compile(name, str, false)
  703. if err != nil {
  704. return nil, err
  705. }
  706. ctx.prgCache[name] = prg
  707. }
  708. return prg, nil
  709. }
  710. func (ctx *tc39TestCtx) runFile(base, name string, vm *Runtime) error {
  711. prg, err := ctx.compile(base, name)
  712. if err != nil {
  713. return err
  714. }
  715. _, err = vm.RunProgram(prg)
  716. return err
  717. }
  718. func (ctx *tc39TestCtx) runTC39Script(name, src string, includes []string, vm *Runtime) (err error, early bool) {
  719. early = true
  720. err = ctx.runFile(ctx.base, path.Join("harness", "assert.js"), vm)
  721. if err != nil {
  722. return
  723. }
  724. err = ctx.runFile(ctx.base, path.Join("harness", "sta.js"), vm)
  725. if err != nil {
  726. return
  727. }
  728. for _, include := range includes {
  729. err = ctx.runFile(ctx.base, path.Join("harness", include), vm)
  730. if err != nil {
  731. return
  732. }
  733. }
  734. var p *Program
  735. p, err = Compile(name, src, false)
  736. if err != nil {
  737. return
  738. }
  739. early = false
  740. _, err = vm.RunProgram(p)
  741. return
  742. }
  743. func (ctx *tc39TestCtx) runTC39Tests(name string) {
  744. files, err := ioutil.ReadDir(path.Join(ctx.base, name))
  745. if err != nil {
  746. ctx.t.Fatal(err)
  747. }
  748. for _, file := range files {
  749. if file.Name()[0] == '.' {
  750. continue
  751. }
  752. if file.IsDir() {
  753. ctx.runTC39Tests(path.Join(name, file.Name()))
  754. } else {
  755. fileName := file.Name()
  756. if strings.HasSuffix(fileName, ".js") && !strings.HasSuffix(fileName, "_FIXTURE.js") {
  757. name := path.Join(name, fileName)
  758. ctx.runTest(name, func(t *testing.T) {
  759. ctx.runTC39File(name, t)
  760. })
  761. }
  762. }
  763. }
  764. }
  765. func TestTC39(t *testing.T) {
  766. if testing.Short() {
  767. t.Skip()
  768. }
  769. if _, err := os.Stat(tc39BASE); err != nil {
  770. t.Skipf("If you want to run tc39 tests, download them from https://github.com/tc39/test262 and put into %s. The current working commit is ddfe24afe3043388827aa220ef623b8540958bbd. (%v)", tc39BASE, err)
  771. }
  772. ctx := &tc39TestCtx{
  773. base: tc39BASE,
  774. }
  775. ctx.init()
  776. //ctx.enableBench = true
  777. t.Run("tc39", func(t *testing.T) {
  778. ctx.t = t
  779. //ctx.runTC39File("test/language/types/number/8.5.1.js", t)
  780. //ctx.runTC39Tests("test/language")
  781. ctx.runTC39Tests("test/language/expressions")
  782. ctx.runTC39Tests("test/language/arguments-object")
  783. ctx.runTC39Tests("test/language/asi")
  784. ctx.runTC39Tests("test/language/directive-prologue")
  785. ctx.runTC39Tests("test/language/function-code")
  786. ctx.runTC39Tests("test/language/eval-code")
  787. ctx.runTC39Tests("test/language/global-code")
  788. ctx.runTC39Tests("test/language/identifier-resolution")
  789. ctx.runTC39Tests("test/language/identifiers")
  790. //ctx.runTC39Tests("test/language/literals") // legacy octal escape in strings in strict mode and regexp
  791. ctx.runTC39Tests("test/language/literals/numeric")
  792. ctx.runTC39Tests("test/language/punctuators")
  793. ctx.runTC39Tests("test/language/reserved-words")
  794. ctx.runTC39Tests("test/language/source-text")
  795. ctx.runTC39Tests("test/language/statements")
  796. ctx.runTC39Tests("test/language/types")
  797. ctx.runTC39Tests("test/language/white-space")
  798. ctx.runTC39Tests("test/built-ins")
  799. ctx.runTC39Tests("test/annexB/built-ins/String/prototype/substr")
  800. ctx.runTC39Tests("test/annexB/built-ins/String/prototype/trimLeft")
  801. ctx.runTC39Tests("test/annexB/built-ins/String/prototype/trimRight")
  802. ctx.runTC39Tests("test/annexB/built-ins/escape")
  803. ctx.runTC39Tests("test/annexB/built-ins/unescape")
  804. ctx.runTC39Tests("test/annexB/built-ins/RegExp")
  805. ctx.flush()
  806. })
  807. if ctx.enableBench {
  808. sort.Slice(ctx.benchmark, func(i, j int) bool {
  809. return ctx.benchmark[i].duration > ctx.benchmark[j].duration
  810. })
  811. bench := ctx.benchmark
  812. if len(bench) > 50 {
  813. bench = bench[:50]
  814. }
  815. for _, item := range bench {
  816. fmt.Printf("%s\t%d\n", item.name, item.duration/time.Millisecond)
  817. }
  818. }
  819. }