Skip to content

Commit babc6cb

Browse files
committed
Finally enable Assembly
There's more tweaks needed, especially around the UI but it seems to mostly work so make it live. Fixes #126
1 parent 488d663 commit babc6cb

File tree

5 files changed

+47
-18
lines changed

5 files changed

+47
-18
lines changed

hole/play.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"context"
77
"embed"
88
"errors"
9+
"fmt"
10+
"os"
911
"os/exec"
1012
"strings"
1113
"syscall"
@@ -19,12 +21,12 @@ const timeout = 7 * time.Second
1921
var answers embed.FS
2022

2123
type Scorecard struct {
22-
Answer string
23-
Args []string
24-
ExitCode int
25-
Pass, Timeout bool
26-
Stderr, Stdout []byte
27-
Took time.Duration
24+
ASMBytes, ExitCode int
25+
Answer string
26+
Args []string
27+
Pass, Timeout bool
28+
Stderr, Stdout []byte
29+
Took time.Duration
2830
}
2931

3032
func getAnswer(holeID, code string) (args []string, answer string) {
@@ -93,6 +95,7 @@ func Play(ctx context.Context, holeID, langID, code string) (score Scorecard) {
9395
score.Args, score.Answer = getAnswer(holeID, code)
9496

9597
var stderr, stdout bytes.Buffer
98+
var asmBytesRead, asmBytesWrite *os.File
9699

97100
ctx, cancel := context.WithTimeout(ctx, timeout)
98101
defer cancel()
@@ -109,7 +112,13 @@ func Play(ctx context.Context, holeID, langID, code string) (score Scorecard) {
109112
// Interpreter
110113
switch langID {
111114
case "assembly":
112-
cmd.Args = []string{"/usr/bin/defasm", "-r"}
115+
var err error
116+
if asmBytesRead, asmBytesWrite, err = os.Pipe(); err != nil {
117+
panic(err)
118+
}
119+
120+
cmd.Args = []string{"/usr/bin/defasm", "--size-out=3", "-r"}
121+
cmd.ExtraFiles = []*os.File{asmBytesWrite}
113122
case "bash":
114123
cmd.Args = []string{"/usr/bin/bash", "-s", "-"}
115124
case "brainfuck":
@@ -194,6 +203,14 @@ func Play(ctx context.Context, holeID, langID, code string) (score Scorecard) {
194203
}
195204
}
196205

206+
// Actual byte count is printed by the assembler.
207+
if langID == "assembly" {
208+
if _, err := fmt.Fscanf(asmBytesRead, "%d", &score.ASMBytes); err != nil {
209+
panic(err)
210+
}
211+
asmBytesRead.Close()
212+
}
213+
197214
const maxLength = 128 * 1024 // 128 KiB
198215

199216
// Trim trailing whitespace.

routes/recent.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/code-golf/code-golf/hole"
99
"github.com/code-golf/code-golf/lang"
1010
"github.com/code-golf/code-golf/session"
11+
"gopkg.in/guregu/null.v4"
1112
)
1213

1314
// Recent serves GET /recent/{lang}
@@ -82,11 +83,12 @@ func Recent(w http.ResponseWriter, r *http.Request) {
8283
defer rows.Close()
8384

8485
type recent struct {
85-
Hole hole.Hole
86-
Lang lang.Lang
87-
Login, Scoring string
88-
Bytes, Chars, Strokes, Rank, TieCount int
89-
Submitted time.Time
86+
Hole hole.Hole
87+
Lang lang.Lang
88+
Login, Scoring string
89+
Bytes, Strokes, Rank, TieCount int
90+
Chars null.Int
91+
Submitted time.Time
9092
}
9193

9294
var recents []recent

routes/solution.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ func Solution(w http.ResponseWriter, r *http.Request) {
9191
ToFile: "Out",
9292
})
9393

94-
if out.Pass && golfer != nil && !experimental && in.Lang != "assembly" {
94+
if out.Pass && golfer != nil && !experimental {
9595
if err := db.QueryRowContext(
9696
r.Context(),
9797
`SELECT earned,
@@ -102,14 +102,20 @@ func Solution(w http.ResponseWriter, r *http.Request) {
102102
new_chars_joint, new_chars_rank, new_chars,
103103
beat_chars
104104
FROM save_solution(
105-
bytes := octet_length($1),
106-
chars := char_length($1),
105+
bytes := CASE WHEN $3 = 'assembly'::lang
106+
THEN $5
107+
ELSE octet_length($1)
108+
END,
109+
chars := CASE WHEN $3 = 'assembly'::lang
110+
THEN NULL
111+
ELSE char_length($1)
112+
END,
107113
code := $1,
108114
hole := $2,
109115
lang := $3,
110116
user_id := $4
111117
)`,
112-
in.Code, in.Hole, in.Lang, golfer.ID,
118+
in.Code, in.Hole, in.Lang, golfer.ID, score.ASMBytes,
113119
).Scan(
114120
pq.Array(&out.Cheevos),
115121
&out.RankUpdates[0].From.Joint,

t/solution.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ constant $code = Q:c:to/ASM/;
7777
text: .string "{ $answer.lines.join: 「\n」 }"; textEnd:
7878
ASM
7979

80-
ok post-solution( :$session :$code :lang<assembly> )<Pass>, 'Passes';
80+
ok post-solution( :$session :$code :lang<assembly> )<Pass>, 'Passes';
8181

8282
is-deeply db, (
8383
{ :code($code-short), :lang<raku>, :scoring<bytes> },
8484
{ :code($code-short-chars), :lang<raku>, :scoring<chars> },
85-
# TODO { :$code, :lang<assembly>, :scoring<bytes> },
85+
{ :$code, :lang<assembly>, :scoring<bytes> },
8686
), 'Inserts only bytes';
8787
};
8888

views/js/hole.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ onload = () => {
117117
if (!langs.find(l => l.id == lang))
118118
lang = 'python';
119119

120+
// Assembly only has bytes.
121+
if (lang == 'assembly')
122+
setSolution(solution = 0);
123+
120124
localStorage.setItem('lang', lang);
121125

122126
history.replaceState(null, '', '#' + lang);

0 commit comments

Comments
 (0)