Skip to content

Commit

Permalink
(fix) test262: don't output to stderr for unrelated errors
Browse files Browse the repository at this point in the history
This should fix some incorrectly wrongly failing tests on
https://test262.fyi
  • Loading branch information
xTrayambak committed Dec 12, 2024
1 parent e9c4303 commit 851f06b
Show file tree
Hide file tree
Showing 14 changed files with 180 additions and 153 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
!*/
!LICENSE

success.txt
failed.txt
balde
*.out
*.log
Expand Down
2 changes: 1 addition & 1 deletion bali.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ description = "The Bali JavaScript Engine"
license = "GPL3"
srcDir = "src"
backend = "cpp"
bin = @["balde", "test262_v2", "test262"]
bin = @["balde", "test262"]
installExt = @["nim"]
binDir = "bin"

Expand Down
11 changes: 8 additions & 3 deletions src/bali/grammar/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -695,23 +695,28 @@ proc parseThrow*(parser: Parser): Option[Statement] =

var
throwStr: Option[string]
throwIdent: Option[string]
throwErr: Option[void] # TODO: implement stuff like `throw new URIError();`

while not parser.tokenizer.eof:
let next = parser.tokenizer.next()

if next.kind == TokenKind.Whitespace and next.whitespace.contains(strutils.Newlines):
if next.kind == TokenKind.Whitespace and next.isNewline():
parser.error UnexpectedToken,
"no line break is allowed between 'throw' and its expression"

if next.kind == TokenKind.String:
throwStr = some(next.str)
break

if !throwStr and !throwErr:
if next.kind == TokenKind.Identifier:
throwIdent = some(next.ident)
break

if !throwStr and !throwErr and !throwIdent:
parser.error Other, "throw statement is missing an expression"

some(throwError(throwStr, throwErr))
some(throwError(throwStr, throwErr, throwIdent))

proc parseReassignment*(parser: Parser, ident: string): Option[Statement] =
info "parser: parsing re-assignment to identifier: " & ident
Expand Down
7 changes: 4 additions & 3 deletions src/bali/grammar/statement.nim
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ type
reIdentifier*: string
reAtom*: MAtom
of ThrowError:
error*: tuple[str: Option[string], exc: Option[void]]
error*: tuple[str: Option[string], exc: Option[void], ident: Option[string]]
of BinaryOp:
binLeft*, binRight*: Statement
op*: BinaryOperation = BinaryOperation.Invalid
Expand Down Expand Up @@ -225,14 +225,15 @@ proc pushImmExpr*(args: var PositionedArguments, expr: Statement) {.inline.} =
{.push checks: off, inline.}
proc throwError*(
errorStr: Option[string], errorExc: Option[void],
errorIdent: Option[string]
): Statement =
if *errorStr and *errorExc:
if *errorStr and *errorExc and *errorIdent:
raise newException(
ValueError,
"Both `errorStr` and `errorExc` are full containers - something has went horribly wrong.",
)

Statement(kind: ThrowError, error: (str: errorStr, exc: errorExc))
Statement(kind: ThrowError, error: (str: errorStr, exc: errorExc, ident: errorIdent))

proc createImmutVal*(name: string, atom: MAtom): Statement =
Statement(kind: CreateImmutVal, imIdentifier: name, imAtom: atom)
Expand Down
7 changes: 6 additions & 1 deletion src/bali/runtime/interpreter.nim
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,11 @@ proc generateIR*(

runtime.ir.passArgument(runtime.index("error_msg", internalIndex(stmt)))
runtime.ir.call("BALI_THROWERROR")
elif *stmt.error.ident:
runtime.ir.passArgument(runtime.index(&stmt.error.ident, defaultParams(fn)))
runtime.ir.call("BALI_THROWERROR")
else:
unreachable
of BinaryOp:
info "emitter: emitting IR for binary operation"
runtime.expand(fn, stmt, internal)
Expand Down Expand Up @@ -855,7 +860,7 @@ proc run*(runtime: Runtime) =
console.generateStdIR(runtime)
math.generateStdIR(runtime)
uri.generateStdIR(runtime)
generateErrorsStdIR(runtime)
errors_ir.generateStdIR(runtime)
base64.generateStdIR(runtime)
json.generateStdIR(runtime)
encodeUri.generateStdIR(runtime)
Expand Down
4 changes: 2 additions & 2 deletions src/bali/stdlib/builtins/test262.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
## Test262 required builtins
## Test262 required builtins/harnesses
##

import std/[strutils, math, options, logging, tables]
Expand All @@ -7,7 +7,7 @@ import mirage/runtime/prelude
import bali/runtime/[normalize, bridge]
import bali/runtime/abstract/to_string
import bali/runtime/[arguments, types, atom_helpers]
import bali/stdlib/errors
import bali/stdlib/errors_common
import bali/internal/sugar
import pretty

Expand Down
45 changes: 3 additions & 42 deletions src/bali/stdlib/errors.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,15 @@ import std/[logging]
import mirage/ir/generator
import mirage/runtime/prelude
import bali/grammar/errors
import bali/runtime/normalize
import bali/runtime/[arguments, atom_helpers, normalize]
import bali/runtime/abstract/to_string
import bali/internal/sugar
import bali/runtime/types

type
DeathCallback* = proc(vm: PulsarInterpreter, exitCode: int = 1)
JSException* = ref object of RuntimeException
name: string = ""

proc DefaultDeathCallback(vm: PulsarInterpreter, exitCode: int = 1) =
quit(exitCode)

var deathCallback*: DeathCallback = DefaultDeathCallback
import bali/stdlib/errors_common

proc setDeathCallback*(fn: DeathCallback) {.inline.} =
deathCallback = fn

proc generateMessage*(exc: JSException, err: string): string =
var msg = "Uncaught "

if exc.name.len > 0:
msg &= exc.name & ':'

msg & err

proc jsException*(msg: string): JSException {.inline.} =
var exc = JSException()
exc.message = exc.generateMessage(msg)

exc

proc logTracebackAndDie*(runtime: Runtime, exitCode: int = 1) =
let traceback = runtime.vm.generateTraceback()
assert *traceback, "Mirage failed to generate traceback!"

stderr.write &traceback & '\n'
deathCallback(runtime.vm, exitCode)

proc typeError*(runtime: Runtime, message: string, exitCode: int = 1) {.inline.} =
## Meant for other Bali stdlib methods to use.
runtime.vm.throw(jsException("TypeError: " & message))
Expand All @@ -62,13 +33,3 @@ proc syntaxError*(
runtime: Runtime, error: ParseError, exitCode: int = 1
) {.inline.} =
runtime.syntaxError(error.message, exitCode)

proc generateErrorsStdIr*(runtime: Runtime) =
info "errors: generate IR interface"

runtime.vm.registerBuiltin(
"BALI_THROWERROR",
proc(op: Operation) =
runtime.vm.throw(jsException(&runtime.vm.registers.callArgs[0].getStr()))
runtime.logTracebackAndDie(),
)
42 changes: 42 additions & 0 deletions src/bali/stdlib/errors_common.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import std/[importutils, strutils]
import mirage/runtime/prelude
import bali/runtime/types
import bali/internal/sugar

privateAccess(PulsarInterpreter)

type
JSException* = ref object of RuntimeException
name: string = ""

DeathCallback* = proc(vm: PulsarInterpreter, exitCode: int = 1)

proc DefaultDeathCallback(vm: PulsarInterpreter, exitCode: int = 1) =
quit(exitCode)

var deathCallback*: DeathCallback = DefaultDeathCallback

proc generateMessage*(exc: JSException, err: string): string =
var msg = "Uncaught "

if exc.name.len > 0:
msg &= exc.name & ':'

msg & err

proc jsException*(msg: string): JSException {.inline.} =
var exc = JSException()
exc.message = exc.generateMessage(msg)

exc

proc logTracebackAndDie*(runtime: Runtime, exitCode: int = 1) =
let traceback = runtime.vm.generateTraceback()
assert *traceback, "Mirage failed to generate traceback!"

if runtime.vm.trace.exception.message.contains(runtime.test262.negative.`type`):
stdout.write(&traceback & '\n')
deathCallback(runtime.vm, exitCode)
else:
stderr.write &traceback & '\n'
deathCallback(runtime.vm, exitCode)
23 changes: 23 additions & 0 deletions src/bali/stdlib/errors_ir.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
## Implementation of the error throw IR builtin
## Refactored here because Nim hates me
## Authors:
## Trayambak Rai (xtrayambak at disroot dot org)
import std/[logging]
import mirage/runtime/prelude
import bali/stdlib/errors_common
import bali/runtime/[arguments, atom_helpers, types]
import bali/runtime/abstract/to_string
import bali/internal/sugar

proc generateStdIr*(runtime: Runtime) =
info "errors: generate IR interface"

runtime.vm.registerBuiltin(
"BALI_THROWERROR",
proc(op: Operation) =
let atom = runtime.argument(1, required = true, message = "BUG: BALI_THROWERROR got {nargs} atoms, expected one!")
runtime.vm.throw(jsException(
runtime.ToString(&atom)
))
runtime.logTracebackAndDie(),
)
4 changes: 2 additions & 2 deletions src/bali/stdlib/prelude.nim
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ./[console, math, uri, errors, json, constants, date]
import ./[console, math, uri, errors, errors_ir, errors_common, json, constants, date]
import ./builtins/[base64, parse_int, test262, encode_uri]

export console, math, uri, parse_int, errors, test262, base64, json, constants, date,
encode_uri
encode_uri, errors_ir, errors_common
99 changes: 0 additions & 99 deletions src/test262_v2.nim

This file was deleted.

Loading

0 comments on commit 851f06b

Please sign in to comment.