1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 10:55:07 +00:00
Commit graph

451 commits

Author SHA1 Message Date
Linus Groh
aef502e8e0 LibJS: Change PropertyName::as_number() return type to u32
This is how it's stored internally - even though we still only construct
from i32. I had the compiler yell at me while trying something with this
and didn't want to add yet another cast, so let's quickly fix this.
2021-04-25 22:42:48 +02:00
Linus Groh
c61de8e4be LibJS: Use Object::get_own_properties() for getOwnPropertyNames() 2021-04-25 22:40:21 +02:00
Linus Groh
af62678c31 LibJS: Don't assume call_frame->current_node in Exception constructor
It's a nullptr in promise reaction job functions, for example. Regressed
in 97d49cb.

Fixes #6641.
2021-04-25 21:45:23 +02:00
FalseHonesty
bee16bb83a LibJS: Don't suppress GlobalObject variable lookup exceptions
In HackStudio's Debugger a custom GlobalObject is used to reflect
debugger variables into the JS scope by overriding GlobalObject's
get method. However, when throwing a custom error during that lookup
it was replaced with the generic "not found" js exception. This patch
makes it instead pass along the custom error.
2021-04-25 19:03:57 +02:00
Linus Groh
b0faf2287a LibJS: Use linusg@serenityos.org for my new copyright headers, too
Whoops, I have a new email for these! :^)
2021-04-24 20:16:31 +02:00
Linus Groh
62c7608a25 LibJS+LibWeb: Move exception logging and remove should_log_exceptions
LibWeb is now responsible for logging unhandled exceptions itself,
which means set_should_log_exceptions() is no longer used and can be
removed. It turned out to be not the best option for web page exception
logging, as we would have no indication regarding whether the exception
was later handled of not.
2021-04-24 20:11:04 +02:00
Linus Groh
08373090ae LibJS: Add VM::on_call_stack_emptied callback
Instead of having to run queued promise jobs in LibWeb in various
places, this allows us to consolidate that into one function - this is
very close to how the spec describes it as well ("at some future point
in time, when there is no running execution context and the execution
context stack is empty, the implementation must [...]").

Eventually this will also be used to log unhandled exceptions, and
possibly other actions that require JS execution to have ended.
2021-04-24 20:11:04 +02:00
Linus Groh
97d49cb92b LibJS: Consolidate exception function names and source ranges
Instead of storing the function names (in a badly named Vector<String>)
and source ranges separately, consolidate them into a new struct:
TracebackFrame. This makes it both easier to use now and easier to
extend in the future.
Unlike before we now keep each call frame's current node source range
in the traceback frame next to the function name, meaning we can display
line and column numbers outside of the VM and after the call stack is
emptied.
2021-04-24 20:11:04 +02:00
Linus Groh
0cf04d07aa LibJS: Temporarily clear exception in Object::get_without_side_effects()
This would return an empty value once it hits an exception check
otherwise. Considering that this mostly is used in situations where we
already *do* have an exception (traceback printing, for example), let's
make this easier for ourselves to use.
2021-04-24 20:11:04 +02:00
Linus Groh
5caab0148c LibJS: Add TemporaryClearException helper class
This is very similar to AK::TemporaryChange (and in fact replaces one
use of it), but since we can't directly set VM's m_exception from
outside of the VM, we need something more sophisticated.
Sometimes we need to temporarily remove the stored exception for some
other operation to succeed (e.g. anything that uses call(), as well as
get_without_side_effects()) and later restore it - the boilerplate code
required for this is annoying enough to justify a helper.
2021-04-24 20:11:04 +02:00
Linus Groh
0053816e9d LibJS: Correctly handle mixing +0 and -0 in Math.{min,max}()
The native C++ < and > operators won't handle this correctly, so the
result was different depending on the order of arguments. This is now
fixed by explicitly checking for positive and negative zero values.

Fixes #6589.
2021-04-23 20:51:48 +02:00
Andreas Kling
b91c49364d AK: Rename adopt() to adopt_ref()
This makes it more symmetrical with adopt_own() (which is used to
create a NonnullOwnPtr from the result of a naked new.)
2021-04-23 16:46:57 +02:00
Ali Mohammad Pur
2ef5b138ee LibJS: Use the match's global offset for 'index' in RegExp.exec()
This was not noticed before because all the previous matches were
single-line.
2021-04-23 10:05:04 +02:00
Matthew Olsson
fcd3b9a0df Userland: Use mattco@serenityos.org for my copyright headers 2021-04-23 08:24:53 +02:00
Linus Groh
ebdeed087c Everywhere: Use linusg@serenityos.org for my copyright headers 2021-04-22 22:51:19 +02:00
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.

See: https://spdx.dev/resources/use/#identifiers

This was done with the `ambr` search and replace tool.

 ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-22 11:22:27 +02:00
Linus Groh
7af1d2c170 LibJS: Make Object.getOwnPropertyDescriptor() work with string indexed property
E.g. for "0" we have to contruct a PropertyName with Type::Number so it
looks in the indexed properties as expected.
2021-04-20 18:53:07 +02:00
Linus Groh
614bad86bc LibJS: Fix Object.getOwnPropertyDescriptor() attributes for numeric property
We were getting the attributes of the existing value and then
immediately assigned the default attributes instead.
2021-04-20 18:42:10 +02:00
Idan Horowitz
63af67ea01 LibJS: Throw on a regex searchString in String.startsWith
As is required by the specification:
"Let isRegExp be ? IsRegExp(searchString). If isRegExp is true,
throw a TypeError exception."
2021-04-20 14:38:54 +02:00
Idan Horowitz
b1e5330e64 LibJS: Stop early-returning on missing searchString in String.startsWith
A missing searchString is allowed by the specification and is treated
as js_undefined. ("undefined test".startsWith() => true)
2021-04-20 14:38:54 +02:00
Linus Groh
ac3e7ef791 LibJS: Fix crash in Object.{freeze,seal}() with indexed properties
This was failing to take two things into account:

- When constructing a PropertyName from a value, it won't automatically
  convert to Type::Number for something like string "0", even though
  that's how things work internally, since indexed properties are stored
  separately. This will be improved in a future patch, it's a footgun
  and should happen automatically.
- Those can't be looked up on the shape, we have to go through the
  indexed properties instead.

Additionally it now operates on the shape or indexed properties directly
as define_property() was overly strict and would throw if a property was
already non-configurable.

Fixes #6469.
2021-04-20 09:38:22 +02:00
Linus Groh
085816645f LibJS: Take PropertyName in Object::set_integrity_level() internal lambda
At least for IntegrityLevel::Frozen we already construct a PropertyName
from the key value, let's reuse that.
2021-04-20 09:38:22 +02:00
Linus Groh
8d490aba76 LibJS: Implement console.assert() 2021-04-18 18:28:17 +02:00
Linus Groh
51676d7c33 LibJS: Use dbgln_if() instead of '#if OBJECT_DEBUG' 2021-04-18 18:10:42 +02:00
Linus Groh
eedde500eb LibJS: Replace MAX_U32 with NumericLimits<u32>::max() 2021-04-17 19:35:32 +02:00
Idan Horowitz
79b1270711 LibJS: Take reference instead of pointer in prepare_arguments_list
This argument is always non-null (and the function assumes so), so
theres no point to taking a pointer instead of a reference.
2021-04-17 17:38:50 +02:00
Idan Horowitz
6cd318d784 LibJS: Convert matched regex result to string in Symbol.replace
This would crash on an undefined match (no match), since the matched
result was assumed to be a string (such as on discord.com). The spec
suggests converting it to a string as well:
https://tc39.es/ecma262/#sec-regexp.prototype-@@replace (14#c)
2021-04-17 16:10:45 +02:00
Idan Horowitz
586f10b6e1 LibJS: Accept symbol property in the in operator
This is used by discord.com and allowed by the specification:
https://tc39.es/ecma262/#sec-relational-operators-runtime-semantics-evaluation
2021-04-17 00:59:36 +02:00
Idan Horowitz
e3c634fdd0 LibJS: Implement initializing a TypedArray from an iterable object
Based on these specifications (which required IterableToList as well):
https://tc39.es/ecma262/#sec-typedarray
https://tc39.es/ecma262/#sec-initializetypedarrayfromlist
2021-04-17 00:24:09 +02:00
Idan Horowitz
06a2173586 LibJS: Implement initializing a TypedArray from an array-like object
Used by twitch.tv and based on the following specification:
https://tc39.es/ecma262/#sec-initializetypedarrayfromarraylike
2021-04-17 00:24:09 +02:00
Idan Horowitz
223472c57f LibJS: Dont try to serialize symbol-keyed properties
As per the specification: "All Symbol-keyed properties will be
completely ignored, even when using the replacer function."
2021-04-16 19:22:29 +02:00
Idan Horowitz
fff7aceb9d LibJS: Accept symbol property in ObjectPrototype::hasOwnProperty
This is used by discord.com and allowed by the specification
(https://tc39.es/ecma262/#sec-topropertykey)
2021-04-16 19:22:29 +02:00
Linus Groh
a5d4ef462c LibJS: Remove #if !defined(KERNEL)
AK::JsonValue::{is,as}_double() is not available in the kernel, but that
doesn't affect LibJS.
2021-04-16 18:57:58 +02:00
Nicholas-Baron
c4ede38542 Everything: Add -Wnon-virtual-dtor flag
This flag warns on classes which have `virtual` functions but do not
have a `virtual` destructor.

This patch adds both the flag and missing destructors. The access level
of the destructors was determined by a two rules of thumb:
1. A destructor should have a similar or lower access level to that of a
   constructor.
2. Having a `private` destructor implicitly deletes the default
   constructor, which is probably undesirable for "interface" types
   (classes with only virtual functions and no data).

In short, most of the added destructors are `protected`, unless the
compiler complained about access.
2021-04-15 20:57:13 +02:00
Timothy Flynn
b6093ae2e3 LibJS: Implement String.prototype.substr according to the spec
Fixes #6325

The JavaScript on the HTML Spec site that caused the crash is:
    window.location.hash.substr(1)

Of course, window.location.hash can be the empty string. The spec allows
for calling substr(1) on an empty string, but our partial implementation
wasn't handling it properly.
2021-04-15 08:38:19 +02:00
Linus Groh
51a5427419 LibJS: Improve Reference::get() TypeError message for nullish base
"ToObject on null or undefined" is useless.
"Cannot get property 'foo' of undefined" isn't.
2021-04-14 22:37:12 +02:00
Idan Horowitz
ba77b40808 LibJS: Implement the encode/decodeURI(Component) family of functions
These are generally useful and in particular needed for twitter.com
2021-04-14 13:30:10 +02:00
Linus Groh
ea60b344eb LibJS: Add name and message properties to NativeError prototypes
Otherwise these will get their name/default message from the Error
prototype, and as a result would always just say "Error" in error
messages, not the specific type.
Something I missed in da177c6, now with tests. :^)
2021-04-14 10:11:04 +02:00
Linus Groh
45133d8ada LibJS: Unset m_unwind_until_label in stop_unwind()
I don't see a reason to keep this intact, that might only surprise us
down the line...
2021-04-13 15:40:52 +02:00
Linus Groh
4ee965f916 LibJS: Add set_exception() and change throw_exception() to take a reference
Sometimes we just want to set m_exception to some value we stored
previously, without really "throwing" it again - that's what
set_exception() does now. Since we have clear_exception(), it does take
a reference, i.e. you don't set_exception(nullptr). For consistency I
updated throw_exception() to do the same.
2021-04-13 15:40:52 +02:00
tuqqu
c8ad1df143 LibJS: Array.from mapFn fixes + thisArg support
* Callback mapFn now properly supports second argument (index)
* Support of thisArg to be passed as "this" in vm.call
* Tests for all cases
2021-04-13 15:16:16 +02:00
Linus Groh
da177c6517 LibJS: Make Errors fully spec compliant
The previous handling of the name and message properties specifically
was breaking websites that created their own error types and relied on
the error prototype working correctly - not assuming an JS::Error this
object, that is.

The way it works now, and it is supposed to work, is:

- Error.prototype.name and Error.prototype.message just have initial
  string values and are no longer getters/setters
- When constructing an error with a message, we create a regular
  property on the newly created object, so a lookup of the message
  property will either get it from the object directly or go though the
  prototype chain
- Internal m_name/m_message properties are no longer needed and removed

This makes printing errors slightly more complicated, as we can no
longer rely on the (safe) internal properties, and cannot trust a
property lookup either - get_without_side_effects() is used to solve
this, it's not perfect but something we can revisit later.

I did some refactoring along the way, there was some really old stuff in
there - accessing vm.call_frame().arguments[0] is not something we (have
to) do anymore :^)

Fixes #6245.
2021-04-12 09:38:57 +02:00
Linus Groh
6e9eb0a284 LibJS: Add Object::get_without_side_effects()
Similar to Value::to_string_without_side_effects() this is mostly a
regular object property lookup, but with the guarantee that it will be
side-effect free, i.e. no accessors or native property functions will
be called. This is needed when we want to access user-controlled object
properties for debug logging, for example. The specific use case will be
error objects which will soon no longer have internal name/message
properties, so we need to guarantee that printing an error, which may
already be the result of an exception, won't blow up in our face :^)
2021-04-12 09:38:57 +02:00
Linus Groh
433a23cfde LibJS: Fix array hole and string object indexing prototype indirection
This fixes two cases of indexed access (array holes, out-of-bounds
string object access) where we would not follow the prototype chain and
incorrectly return undefined:

    // Should be "a", returned undefined
    Object.setPrototypeOf([,], ["a"])[0]

    // Should be "a", returned undefined
    Object.setPrototypeOf(new String(""), new String("a"))[0]

The actual fix is simple, instead of returning early if the requested
index is past the string's length or within the indexed properties size
but has no value, we just continue the prototype chain traversal and get
correct behaviour from that.
2021-04-11 18:15:47 +02:00
Luke
ccd21614a3 LibJS: Replace Vector with MarkedValueList in RegExpPrototype::symbol_replace
Otherwise the GC won't be able to keep track of the stored values
and they may suddenly disappear from underneath us, thinking
they're not in use.

Fixes a crash when going to the Bootstrap website, where the first
replace call in jQuery caused a jump to a bogus address.
2021-04-11 00:32:59 +02:00
AnotherTest
a6e4482080 AK+Everywhere: Make StdLibExtras templates less wrapper-y
This commit makes the user-facing StdLibExtras templates and utilities
arguably more nice-looking by removing the need to reach into the
wrapper structs generated by them to get the value/type needed.
The C++ standard library had to invent `_v` and `_t` variants (likely
because of backwards compat), but we don't need to cater to any codebase
except our own, so might as well have good things for free. :^)
2021-04-10 21:01:31 +02:00
Linus Groh
9cd010167a LibJS: Implement Object.create() 2021-04-10 21:00:04 +02:00
Linus Groh
da8a35a79e LibJS: Implement Object.defineProperties() 2021-04-10 21:00:04 +02:00
Linus Groh
275da6fcc9 LibJS: Update Object::define_accessor() to take both getter and setter
This replaces the current 'function plus boolean indicating the type'
API, which makes it easier to set both getter and setter at once.
This was already possible before but required two calls of this
function, which wasn't intuitive:

    define_accessor(name, getter, true, ...);
    define_accessor(name, setter, false, ...);

Which now becomes:

    define_accessor(name, getter, setter, ...);
2021-04-10 21:00:04 +02:00
Linus Groh
ec62783af9 LibJS: Let Object::delete_property() return a bool, not Value
Just like the various define_property functions, this should return a
bool directly and let the caller deal with wrapping it in a Value, if
necessary.
2021-04-10 21:00:04 +02:00