This code isn't _actually_ used as of right now, but I wrote it at the
same time as all of the code in the previous commit. I realized after
I wrote it that these hint tables aren't super useful if the parser
already has access to the full file. However, this will be useful if
we ever want to stream PDFs from the web (and possibly view them in
the browser).
This is a big step, as most PDFs which are downloaded online will be
linearized. Pretty much the only difference is that the xref structure
is slightly different.
- A newline was assumed to follow the "stream" keyword, when it can also
be a windows-style line break
- Fix not consuming the "endobj" at the end of every indirect object
The Parser should hold information relevant for parsing, whereas the
Document should hold information relevant for displaying pages.
With this in mind, there is no reason for the Document to hold the
xref table and trailer. These objects have been moved to the Parser,
which allows the Parser to expose less public methods (which will be
even more evident once linearized PDFs are supported).
This counter is increased each time a synchronous execution sequence
completes, and will allow us to emulate the abstract operations
AddToKeptObjects & ClearKeptObjects efficiently.
Let clients manage their own window ID's. If you try to create a new
window with an existing ID, WindowServer will simply disconnect you
for misbehaving.
This removes the need for window creation to be synchronous, which
means that most GUI applications can now batch their entire GUI
initialization sequence without having to block waiting for responses.
This shows all selected inodes in their parent directory.
Currently, each selection makes a seperate call to LaunchServer
and opens a seperate FileManager window. In the future selections
with a shared parent could share windows.
Whether or not tiles moved used to be determined by comparing new_tiles
with m_tiles. This is no longer possible since the slide is done
in-place.
This fix makes the game look through the m_sliding_tiles, which contains
previous and current position for each tile on the board, to determine
whether any tile moved at all. If not, the move is deemed unsuccessful.
Fixes#8008.
This is very similar to Object::define_native_property, but here the
native functions are exported as standalone JS getter and setter
functions, instead of being transparently called by interactions with
the property.
Keeping this as a separate commit as I'm not certain whether this
is a good change or not. The repeated if-else for each Foundation
stack bothered me a bit, though more so before I reduced the code
in the {}. But maybe the ifs are clearer than the loop?
Doing that also meant I could inline the move_card() code instead
of needing to make it a lambda. Again, maybe it would be better as
a lambda? I'm still figuring out the style Serenity uses, and I
know Andreas is big on expressiveness, and move_card() is more
expressive than just having the code in the loop.
The two paths did the same thing, in two different ways. Now they
are the same. :^)
Can't quite put all of the logic into
attempt_to_move_card_to_foundations() because the double-click has
to check that you clicked on the top card.
Some of this stuff is already tested properly in the name and message
prototype tests, so let's focus on covering all error types here as well
instead.
This commit doesn't include support for FETCH BODY, because it's a bit
big already. Rest assured, FETCH is the most complicated IMAP command,
and we'll go back to simple boring ones shortly.
DateTime can now be parsed from a string. Implements the same formatters
as strptime: https://linux.die.net/man/3/strptime (Well, some of them at
least).
The fact that they *are* subclasses is an implementation detail and
should not be highlighted. The spec calls these NativeErrors, so let's
use that.
Also added a comment explaining *why* they inherit from Error - I was
about to change that :^)
The property name in an object literal can either be a literal or a
computed name, in which case any AssignmentExpression can be used, we
now only parse AssignmentExpression instead of the previous incorrect
behaviour which allowed any Expression (Specifically, comma
expressions).
Doing these as custom classes might be faster, especially when writing
them in SSE, but this would cause a lot of Code duplication and due to
the nature of constexprs and the intelligence of the compiler they might
be using SSE/MMX either way
This enables the WebServer to run protected by a username and password.
While it isn't possible to access such a protected server from inside
Serenity as of now (because neither the Browser nor pro(1) support
this), this may very well be the case in the future. :^)
This patch adds two new static methods to HttpRequest.
get_http_basic_authentication_header generates a "Authorization" header
from a given URL, where as parse_http_basic_authentication_header parses
an "Authorization" header into username and password.
This moves the configuration of the web server, which currently only
consists of the root path, into a new class, Configuration. Since the
configuration is global and not per client, it is accessed by a
singleton getter.
This change simplifies future extensions of the configurable parameters.
This changes the Client::set_error_response() to not take a "message"
anymore. It now uses the canonical reason phrase which is derived from
the response code.
This adds trailing slashes to all links to directories (when listing the
directory contents). This avoids the redirect that would otherwise
happen when browsing to those directories.
In the web server root directory, ".." has to be handled specially,
since everything above it does not exist from the point of view of the
user. The most sensible thing to do is to make ".." equal to ".". This
is also what ls(1) does for "/" and what "http://localhost/../"
evaluates to.
This also fixes a bug where stat() would fail on the directory above the
root directory, since it hasn't been unveiled for the process.
The addition of an is_generator parameter broke this, as is_strict was
being passed in, causing an assertion.
This is being addressed by changing it to an enum in #7981, but in the
meantime let's just fix these two cases.
20.5.1.1 Error ( message )
When the Error function is called with argument message, the
following steps are taken:
[...]
3b. Let msgDesc be the PropertyDescriptor {
[[Value]]: msg,
[[Writable]]: true,
[[Enumerable]]: false,
[[Configurable]]: true
}.
3c. Perform ! DefinePropertyOrThrow(O, "message", msgDesc).
The FunctionPrototype is correct for ErrorConstructor itself:
20.5.2 Properties of the Error Constructor
The Error constructor:
- has a [[Prototype]] internal slot whose value is
%Function.prototype%.
However, not for all the other "NativeError" constructors:
20.5.6.2 Properties of the NativeError Constructors
Each NativeError constructor:
- has a [[Prototype]] internal slot whose value is %Error%.
Non-RangeError exceptions can be thrown by user implementations of
valueOf (which are called by to_index), and the specification disallows
changing the type of the thrown error.
The second argument (the default constructor) and the return value have
to be constructors (as a result functions), so we can require that
explicitly by using appropriate types.
The `c_iflag` and `c_oflag` fields were swapped in the source code which
caused the bit values to be interpreted as the wrong flag. It was a
stupid mistake on my part.
This patch adds a CallType to the Bytecode::Op::Call instruction,
which can be either Call or Construct. We then generate Construct
calls for the NewExpression AST node.
When executed, these get fed into VM::construct().
This adds a new PushLexicalEnvironment instruction that creates a new
LexicalEnvironment and pushes it on the VM's scope stack.
There is no corresponding PopLexicalEnvironment instruction yet,
so this will behave incorrectly with let/const scopes for example.
This replaces Bytecode::Op::EnterScope with a new NewFunction op that
instantiates a ScriptFunction from a given FunctionNode (AST).
This is then used to instantiate the local functions directly from
bytecode when entering a ScopeNode. :^)
These will be partly handled by the relevant ScopeNode due to
hoisting, same basic idea as function declarations.
VariableDeclaration needs to do some work, but let's stub it out
first and start empty.
EnterUnwindContext pushes an unwind context (exception handler and/or
finalizer) onto a stack.
LeaveUnwindContext pops the unwind context from that stack.
Upon return to the interpreter loop we check whether the VM has an
exception pending. If no unwind context is available we return from the
loop. If an exception handler is available we clear the VM's exception,
put the exception value into the accumulator register, clear the unwind
context's handler and jump to the handler. If no handler is available
but a finalizer is available we save the exception value + metadata (for
later use by ContinuePendingUnwind), clear the VM's exception, pop the
unwind context and jump to the finalizer.
ContinuePendingUnwind checks whether a saved exception is available. If
no saved exception is available it jumps to the resume label. Otherwise
it stores the exception into the VM.
The Jump after LeaveUnwindContext could be integrated into the
LeaveUnwindContext instruction. I've kept them separate for now to make
the bytecode more readable.
> try { 1; throw "x" } catch (e) { 2 } finally { 3 }; 4
1:
[ 0] EnterScope
[ 10] EnterUnwindContext handler:@4 finalizer:@3
[ 38] EnterScope
[ 48] LoadImmediate 1
[ 60] NewString 1 ("x")
[ 70] Throw
<for non-terminated blocks: insert LeaveUnwindContext + Jump @3 here>
2:
[ 0] LoadImmediate 4
3:
[ 0] EnterScope
[ 10] LoadImmediate 3
[ 28] ContinuePendingUnwind resume:@2
4:
[ 0] SetVariable 0 (e)
[ 10] EnterScope
[ 20] LoadImmediate 2
[ 38] LeaveUnwindContext
[ 3c] Jump @3
String Table:
0: e
1: x
This commit adds support for these escape sequences that are used for
scrolling multiple lines at once. In the current, unoptimized
implementation, these just call the `scroll_left` and `scroll_right`
APIs multiple times.
It's a VT420 feature.
If lines are removed from the tail of the scrollback buffer, the
previous line indices will refer to different lines; therefore we need
to offset them.
These escape sequences are the horizontal scrolling equivalents of `IND`
and `RI`. Normally, they move the cursor forward or backward. But if
they hit the margins (which we just treat as the first and last
columns), they scroll the line.
Another VT420 feature done.
This commit implements the left/right scrolling used in the `ICH`/`DCH`
escape sequences for `VirtualConsole`. This brings us one step closer to
VT420/xterm compatibility.
We can now finally remove the last escape sequence related `ifdef`s.
Previously, this was done by telling the client to put a space at each
character in the range. This was inefficient, because a large number of
function calls took place and incorrect, as the ANSI standard dictates
that character attributes should be cleared as well.
The newly added `clear_in_line` function solves this issue. It performs
just one bounds check when it's called and can be implemented as a
pretty tight loop.
Previously, we would remove lines from the buffer, create new lines and
insert them into the buffer when we scrolled. Since scrolling does not
always happen at the last line, this meant `Line` objects were
pointlessly moved forwards, and then immediately backwards.
We now swap them in-place and clear those lines that are "inserted". As
a result, performance is better and scrolling is smoother in `vim` and
`nano`.
The `num` parameter should be treated as an offset from the cursor
position, not from the beginning of the line. The previous behavior
caused fragments of previous lines to be visible when moving the entire
buffer in vim (e.g. with `gg` and `G`).
The debug messages I used while fixing it are also included in this
commit. These will help diagnose further issues if they arise.
This commit cleans up some of the `#ifdef`-ed code smell in
`Terminal`, by extending the scroll APIs to take a range of lines as a
parameter. This makes it possible to use the same code for `IL`/`DL` as
for scrolling.
Note that the current scrolling implementation is very naive, and does
many insertions/deletions in the middle of arrays, whereas swaps should
be enough. This optimization will come in a later commit.
The `linefeed` override was removed from `VirtualConsole`. Previously,
it exhibited incorrect behavior by moving to column 0. Now that we use
the method defined in `Terminal`, code which relied on this behavior
stopped working. We go instead go through the TTY layer which handles
the various output flags. Passing the input character-by-character
seems a bit excessive, so a fix for it will come in another PR.
Previously, entering too big counts for these commands could cause a
wrap-around with the cell indices.
Also, we are now correctly copying the cell attributes as well as the
code point.
More specifically, Array.prototype.splice. Additionally adds a missing
exception check to the array creation and a link to the spec.
Fixes create-non-array-invalid-len.js in the splice tests in test262.
This test timed out instead of throwing an "Invalid array length"
exception.
We already have two separate implementations of this, so let's do it
properly. The optional value type check is done by a callback function
that returns Result<void, ErrorType> - value type accepted or message
for TypeError, that is.
"let" and "const" go in the lexical environment.
This fixes one part of #4001 (Lexically declared variables are mixed up
with global object properties)
We can now handle access-specifier tags (for example 'private:') when
parsing class declarations.
We currently only consume these tags on move on. We'll need to add some
logic that accounts for the access level of symbols down the road.
Previously, we had a special ASTNode for class members,
"MemberDeclaration", which only represented fields.
This commit removes MemberDeclaration and instead uses regular
Declaration nodes for representing the members of a class.
This means that we can now also parse methods, inner-classes, and other
declarations that appear inside of a class.
This was creating a ton of pointless busywork for the garbage collector
and can be avoided simply by tolerating that the current call frame has
a null scope object for the duration of a NativeFunction activation.
It's prone to finding "technically uninitialized but can never happen"
cases, particularly in Optional<T> and Variant<Ts...>.
The general case seems to be that it cannot infer the dependency
between Variant's index (or Optional's boolean state) and a particular
alternative (or Optional's buffer) being untouched.
So it can flag cases like this:
```c++
if (index == StaticIndexForF)
new (new_buffer) F(move(*bit_cast<F*>(old_buffer)));
```
The code in that branch can _technically_ make a partially initialized
`F`, but that path can never be taken since the buffer holding an
object of type `F` and the condition being true are correlated, and so
will never be taken _unless_ the buffer holds an object of type `F`.
This commit also removed the various 'diagnostic ignored' pragmas used
to work around this warning, as they no longer do anything.
This enables support for playing float32 and float64
WAVE_FORMAT_EXTENSIBLE files.
The PCM data format is encoded in the
first two bytes of the SubFormat GUID inside of the
WAVE_FORMAT_EXTENSIBLE `fmt` chunk.
Also, fixed the RIFF header size check to allow up to
maximum_wav_size (currently defined as 1 GiB).
The RIFF header size is the size of the entire
file, so it should be checked against the largest Wave size.
This fixes#7131
The parser already distinguishes between inline code (handled in
Text.cpp) and triple-tick code blocks, so only
CodeBlock::render_to_html() needed to change. Blank lines within
a code block still cause issues, but that's an HTML issue. (#7121)
This makes sure that is<Set> checks done on the Set prototype instead of
on Set instances return false, thereby emulating the behaviour of the
RequireInternalSlot abstract operation.
This fixes#7946
Previously, TextEditor::write_to_file() would not mark its document
as unmodified if the file size was 0. This caused a desync in the
Text Editor app between the window's is_modified state and the
TextEditor's. It's already noted in the comments of the app's
save action code that propagating the modified state automatically
would be good, and it would solve issues like this, but I'm not yet
familiar enough with the code to try a change like that.
Instead of using Strings in the bytecode ops this adds a global string
table to the Executable struct which individual operations can refer
to using indices. This brings bytecode ops one step closer to being
pointer free.
This adds a FileWatcher to the LookupServer which watches '/etc/hosts'
for changes during runtime and reloads its contents. If the file is
deleted, m_etc_hosts will be cleared.
Since we now need to access '/etc/hosts' later during runtime, it needs
to be unveiled with read permissions.
This reworks the LookupServer::load_etc_hosts() method to use the
IPv4Address APIs instead of trying to parse an IPv4 address itself.
It also adds a few error checks for invalid entries in /etc/hosts,
trims away leading and trailing whitespace from lines and tries to use
StringView over String.
This fixes a bug where if you try to play a Wave file a second
time (or loop with `aplay -l`), the second time will be pure
noise.
The function `Audio::Loader::seek` is meant to seek to a specific
audio sample, e.g. seek(0) should go to the first audio sample.
However, WavLoader was interpreting seek(0) as the beginning
of the file or stream, which contains non-audio header data.
This fixes the bug by capturing the byte offset of the start of the
audio data, and offseting the raw file/stream seek by that amount.
While this implementation should be complete it is based on HashTable's
iterator, which currently follows bucket-order instead of the required
insertion order. This can be simply fixed by replacing the underlying
HashTable member in Set with an enhanced one that maintains a linked
list in insertion order.
Added Increment and Decrement bytecode ops to support this. Postfix
updates use a temporary register to preserve the original value.
Note that this patch only implements Identifier updates. Member
expression updates are a TODO.
This is a very basic implementation of glGetfloatv. It will only give a
result when used with GL_MODELVIEW_MATRIX. In the future
we can update and extend it's functionality.
This limits the size of each block (currently set to 1K), and gets us
closer to a canonical, more easily analysable bytecode format.
As a result of this, "Labels" are now simply entries to basic blocks.
Since there is no more 'conditional' jump (as all jumps are always
taken), JumpIf{True,False} are unified to JumpConditional, and
JumpIfNullish is renamed to JumpNullish.
Also fixes#7914 as a result of reimplementing the loop logic.
Previously useradd would not check if a username already existed on the
system, and would instead add the user anyway and just increment the
uid. useradd should instead return an error when the user attempts to
create already existing users.
This change removes the mmap inside of Block in favor of a growing
vector of bytes. This is favorable for two reasons:
- We don't take more space than we need
- There is no limit to the growth of the vector (previously, if
the Block overstepped its 64kb boundary, it would just crash)
However, if that vector happens to resize, any pointer pointing into
that vector would become invalid. To avoid this, this commit adds an
InstructionHandle<Op> class which just stores a block and an offset
into that block.
This was missing from Value::is_array(), which is equivalent to the
spec's IsArray() abstract operation - it treats a Proxy value with an
Array target object as being an Array.
It can throw, so needs both the global object and an exception check
now.
This ensures that "while", do...while, "for" expressions have a
properly initialized result value even if the user terminated
the loop body via break or the loop body wasn't executed at all.