profile
viewpoint
Gus Caplan devsnek @nodejs @tc39 @WebAssembly @OpenJS-Foundation The Open Web https://gc.gy maker of overly complex interpreted languages | they/them

devsnek/discord-rich-presence 66

Discord RPC but only the rich presence part

devsnek/earl 8

Pure JavaScript ETF encoder/decoder

devsnek/ecma-operator-overloading 6

proposal for ecmascript operator overloading

devsnek/discord_bouncer 4

A fast and simple way to communicate with the Discord API

devsnek/boop-teh-snek 3

award winning game

devsnek/benchmark 2

benchmark like a pro, wherever you go

issue commentnodejs/node

SIGSEGV in node::GetErrorSource

@gireeshpunathil consistently 0x2c6d

devsnek

comment created time in 6 hours

issue openednodejs/node

SIGSEGV in node::GetErrorSource

I'm planning to debug this at some point in the next week or so but if someone wants to get started sooner here's what I've got:

Using master as of 9949a2e1e3100c4ff1f228bac57c1af95cdc3e9d. Using linux64.

Process 661308 launched: '/home/snek/bin/node-dev' (x86_64)
Process 661308 stopped
* thread #1, name = 'node-dev', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
    frame #0: 0x0000555555cbcfd9 node-dev`node::GetErrorSource[abi:cxx11](v8::Isolate*, v8::Local<v8::Context>, v8::Local<v8::Message>, bool*) + 1017
node-dev`node::GetErrorSource[abi:cxx11](v8::Isolate*, v8::Local<v8::Context>, v8::Local<v8::Message>, bool*):
->  0x555555cbcfd9 <+1017>: cmp    byte ptr [rdx], 0x0
    0x555555cbcfdc <+1020>: je     0x555555cbcff5            ; <+1045>
    0x555555cbcfde <+1022>: mov    byte ptr [rbp + rcx - 0xca0], 0x5e
    0x555555cbcfe6 <+1030>: add    rcx, 0x1
(lldb) bt
* thread #1, name = 'node-dev', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)
  * frame #0: 0x0000555555cbcfd9 node-dev`node::GetErrorSource[abi:cxx11](v8::Isolate*, v8::Local<v8::Context>, v8::Local<v8::Message>, bool*) + 1017
    frame #1: 0x0000555555cbd332 node-dev`node::AppendExceptionLine(node::Environment*, v8::Local<v8::Value>, v8::Local<v8::Message>, node::ErrorHandlingMode) + 130
    frame #2: 0x0000555555cbd775 node-dev`node::ReportFatalException(node::Environment*, v8::Local<v8::Value>, v8::Local<v8::Message>, node::EnhanceFatalException) + 133
    frame #3: 0x0000555555cbe84e node-dev`node::errors::TriggerUncaughtException(v8::Isolate*, v8::Local<v8::Value>, v8::Local<v8::Message>, bool) + 446
    frame #4: 0x0000555555cbe3f1 node-dev`node::errors::PerIsolateMessageListener(v8::Local<v8::Message>, v8::Local<v8::Value>) + 721
    frame #5: 0x0000555555f83409 node-dev`v8::internal::MessageHandler::ReportMessageNoExceptions(v8::internal::Isolate*, v8::internal::MessageLocation const*, v8::internal::Handle<v8::internal::Object>, v8::Local<v8::Value>) + 361
    frame #6: 0x0000555555f83253 node-dev`v8::internal::MessageHandler::ReportMessage(v8::internal::Isolate*, v8::internal::MessageLocation const*, v8::internal::Handle<v8::internal::JSMessageObject>) + 835
    frame #7: 0x0000555555f773dd node-dev`v8::internal::Isolate::ReportPendingMessagesImpl(bool) + 493
    frame #8: 0x0000555555f66197 node-dev`v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) + 2679
    frame #9: 0x0000555555f656ff node-dev`v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) + 223
    frame #10: 0x0000555555e4f21e node-dev`v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) + 478
    frame #11: 0x0000555555c8f45f node-dev`node::ExecuteBootstrapper(node::Environment*, char const*, std::vector<v8::Local<v8::String>, std::allocator<v8::Local<v8::String> > >*, std::vector<v8::Local<v8::Value>, std::allocator<v8::Local<v8::Value> > >*) + 127
    frame #12: 0x0000555555c9095e node-dev`node::StartExecution(node::Environment*, char const*) + 430
    frame #13: 0x0000555555c90676 node-dev`node::StartExecution(node::Environment*, std::function<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const&)>) + 1254
    frame #14: 0x0000555555c2df3c node-dev`node::LoadEnvironment(node::Environment*) + 76
    frame #15: 0x0000555555d0bc27 node-dev`node::NodeMainInstance::Run() + 183
    frame #16: 0x0000555555c923d3 node-dev`node::Start(int, char**) + 259
    frame #17: 0x00007ffff7a76002 libc.so.6`__libc_start_main + 242
    frame #18: 0x0000555555c2863e node-dev`_start + 46
(lldb) 
'use strict';

const { WASI } = require('wasi');
const fs = require('fs');

const wasi = new WASI();

const m = new WebAssembly.Module(fs.readFileSync('./repro.wasm'));
const w = new WebAssembly.Instance(m, {
  wasi_snapshot_preview1: wasi.wasiImport,
});

w.exports._start(); // throws exception
// rustc repro.rs -O --target wasm32-wasi
fn main() {
    panic!()
}

In the more complex code this was reduced from, the exception thrown by running w.exports.whatever() is from the actual wasm unreachable instruction generated by the panic!(). In this reduced test case, the exception thrown is from node wasi, complaining about wasi.start(w) not being called yet. In both cases, node::GetErrorSource is the point of failure.

created time in 7 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

I can't imagine it comes up that often but I think js is enough of a general purpose language that we can assume someone will run into that.

bakkot

comment created time in 10 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@erights yes that sounds right. its worth noting though you might not be explicitly using infinity, but something could have overflowed.

bakkot

comment created time in 10 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

I am trying to understand what is it about numeric computations that motivates the two zeros, and what is lost if the distinction were collapsed.

Very small negative numbers underflow to -0 because if they underflowed to +0 they would have the wrong sign when you tried to extrapolate further calculations or decisions from them. Additionally, multiplying 0 by a negative number results in -0. I'm not sure why that is but it is common enough (see above examples) that its definitely a foot gun if people have to explicitly watch out for it.

bakkot

comment created time in 11 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@erights yeah i don't care about nan as much, as it doesn't really have bearing on the correctness of successful numeric operations. my argument there was more about staying consistent with the operator being used.

bakkot

comment created time in 11 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

got it. it seems that python also treats -0.0 and 0.0 as equal, but can tell them apart using the is operator.

bakkot

comment created time in 11 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

you said that both n = float('nan'); (0, n) == (0, n) and (0, float('nan')) != (0, float('nan')).

bakkot

comment created time in 11 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

why does factoring nan into a variable change how == works

bakkot

comment created time in 12 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

As for all the other various operators, maybe they're worth discussing, but this issue is about what === should do so I don't see much point in debating the other operators.

bakkot

comment created time in 13 hours

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

+1 @guybedford

jkrems

comment created time in 13 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@littledan because the === operator already does that kind of comparison on numbers. if we had an operator for Object.is semantics (maybe adding that could solve this dispute) it would be fine for it to use Object.is semantics on the elements.

bakkot

comment created time in 13 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@littledan I'm confused, are you saying we shouldn't let === work on these structures at all?

bakkot

comment created time in 13 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Maybe we can add Object.strictEquals so we can still compare the structures correctly even if === is broken.

bakkot

comment created time in 14 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

fwiw my concerns aren't really specific to node.

devsnek

comment created time in 14 hours

issue commentopenjs-foundation/standards

Discuss foundation TC39 delegate expectations

To be clear, I'm not planning to object if I don't feel like I'm comfortably within our expectations of delegates.

ljharb

comment created time in 16 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@papb yeah, saying it is not like a value was imprecise and hopefully my clarification helped.

bakkot

comment created time in 17 hours

issue commentopenjs-foundation/standards

Discuss foundation TC39 delegate expectations

I think if a delegate has technical concerns that have some bearing in reality, it's reasonable for them to block on that without having to muster up the consensus of the org. However if the decision is more principled than that (for example blocking a proposal from stage 1 because they don't think the feature belongs in js or whatever) that requires more consensus.

ljharb

comment created time in 18 hours

pull request commentWebAssembly/WASI

Add support for multi-call executables

We have a use case in node for wasi binaries which use a _napi_init entry point (and don't have _start)

sunfishcode

comment created time in 19 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@bakkot sorry to clarify: if you think of a proxy, it is its own value, but it derives its existence from something else. when you're talking about a proxy you're normally talking about its handlers or its target, not the proxy instance itself. in a similar way tuples, at least in other programming languages, are less about the tuple instance itself and more about what it contains. i think it's unintuitive for a lot of people to even think of a tuple as having behaviour.

bakkot

comment created time in 19 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@bakkot there are still only three values that cause those checks to return true instead of false, they just might be inside the tuples you're comparing.

bakkot

comment created time in 19 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

I'm hoping we can just constructively find consensus, in either direction.

devsnek

comment created time in 19 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

I think adding an infinite set of values for which === and Object.is disagree, where currently there are exactly three such values, would complicate the operator considerably.

I think this depends on your point of view. From my perspective, it's still only three values, and the operator doesn't change.

bakkot

comment created time in 20 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

@MylesBorins I agree this is definitely not the best situation. I opened this issue to discuss it and come to some conclusion, possibly (hopefully) involving consensus.

devsnek

comment created time in 20 hours

issue commentopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

@MylesBorins i think discussion is fine (not allowing discussion would probably be bad for the goal of allowing forward progress), though if we eventually landed on some sort of voting procedure it might make sense to recuse yourself from that.

devsnek

comment created time in 21 hours

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

unless we work hard to educate JS programmers not to do === on Records and Tuples

Is the assumption here that complex memoization code will be way more common than wanting to put a couple of numbers into a record?

bakkot

comment created time in a day

issue openedopenjs-foundation/standards

[TC39] Potentially blocking "Module Attributes" proposal

"Module Attributes" (https://github.com/tc39/proposal-module-attributes) is requesting advancement to stage 2. Currently my concerns for the proposal are as follows:

  • Cache semantics

    • Per-module cache break from (resolver, specifier) pairs
    • Global cache break in real world implementations
    • Modules cannot portably access metadata
  • One-to-many module model

    • Module metadata should be associated once per module within an implementation
  • Standardized handling of parameters

    • Host-specific metadata is not portable
    • Security invariants may be broken if a host ignores an attribute or interprets it incorrectly

Stage 2 requests that all major semantics are covered, and these seem fairly major to me, so I'm not sure this proposal should continue to stage 2 quite yet.

Delegate expectations are still in the works (#84) so I'm not really sure what the process here should be.

created time in a day

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@littledan right so... given different people have different intuitions, and that we have both === and Object.is in the language, why not enable both? It also means you don't have to explain it like "they have the identity of their children except for certain double bit patterns".

bakkot

comment created time in a day

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@littledan isn't one of the main points of these structures that they don't have their own identity, but rather have an identity based on what they contain?

bakkot

comment created time in a day

pull request commentnodejs/node

v8: patch for thenables in PromiseHook API

https://crrev.com/c/2215624

Qard

comment created time in a day

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@erights yes, but as I keep saying you can't normalize -0 to 0...

bakkot

comment created time in 2 days

Pull request review commentnodejs/node

v8: patch for thenables in PromiseHook API

 void MicrotaskQueueBuiltinsAssembler::RunSingleMicrotask(     const TNode<Object> thenable = LoadObjectField(         microtask, PromiseResolveThenableJobTask::kThenableOffset); +    // Run the promise before/debug hook if enabled.+    RunPromiseHook(Runtime::kPromiseHookBefore, microtask_context,

I'm looking through the history of promise hooks (v8:4643 and such) trying to understand why this would've been left out and I haven't found anything, but it does seem suspicious...

Qard

comment created time in 2 days

pull request commentnodejs/node

v8: patch for thenables in PromiseHook API

I can submit this upstream in V8 if you would like.

Qard

comment created time in 2 days

issue closeddevsnek/discord-rich-presence

Accepting game invites

How do i receive game join requests?

closed time in 2 days

NanoCellWebDesign

issue commentdevsnek/discord-rich-presence

Accepting game invites

client.on('joinRequest', (user) => { ... })

NanoCellWebDesign

comment created time in 2 days

issue commentnodejs/node

feature-request fs.fileWrite with option.mkdirp

I assume you don't have 100+ output directories though?

kaizhu256

comment created time in 2 days

issue commentnodejs/node

feature-request fs.fileWrite with option.mkdirp

Given that you can just do this (recursive mkdir doesn't throw if the directory already exists):

fs.mkdirSync(path.dirname(file), { recursive: true });
fs.writeFileSync(file, data);

I don't personally think adding the option is needed.

kaizhu256

comment created time in 2 days

issue commentWebAssembly/design

Proposal: Await

When code is running, and it calls a function, there are two possibilities: It knows that the function will not call random things, or the function might call random things. In the latter case, re-entrancy is always possible.

kripken

comment created time in 2 days

Pull request review commentnodejs/node

events: initial implementation of experimental EventTarget

+'use strict';++const {+  ArrayFrom,+  Object,+  Map,+  SafeWeakMap,+  Set,+  SymbolFor,+} = primordials;++const {+  codes: {+    ERR_INVALID_ARG_TYPE,+    ERR_INVALID_THIS,+    ERR_EVENT_RECURSION,+  }+} = require('internal/errors');+const kRejection = SymbolFor('nodejs.rejection');++const perf_hooks = require('perf_hooks');+const { customInspectSymbol } = require('internal/util');+const { inspect } = require('util');++const events = new SafeWeakMap();+const targets = new SafeWeakMap();

dw i also prefer symbols

jasnell

comment created time in 2 days

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Aside from consistency (which is, in general, a totally valid argument), does anyone have an application/use case where it would be useful to get this sort of nested treatment of NaN/-0 in ==/===?

An example was posted above, twice in fact.

Separately, if you expect this recursive treatment for === in NaN/-0, do you expect == on Records and Tuples to do things like compare BigInts and Numbers as equal when they have the same mathematical value?

I expect == to do what == does, === to do what === does, and Object.is to do what Object.is does. I'm actually not aware of any languages with tuples where equality is defined in terms of something other than recursively applying the operator to the children. They either don't come with their own equality (a op b doesn't compile, and you have to define your own op implementation for it) or they are defined by their children (a op b is true if the children are in the same order and op is true for them).

Personally, I think all of these expectations around recursiveness face the category error @erights pointed out: because we don't have a syntactically convenient "are these exactly the same thing" vs "are these IEEE754/mathematically the same" operator difference, people are going to use === when, for Records and Tuples, the real goal is to find whether they are exactly the same thing. I claim that "are these the same thing" is actually what people are trying to ask when they compare Records and Tuples with ===. I'd say, we should go with the answer to the question they're intending to ask, and let programmers manually recurse and apply the right IEEE754/mathematical comparison operator if that's what they really want.

As has been noted above, people don't often want that. Even if your code has signed zeros at some point, you usually don't even know about them or worry about them, because == and === handle them correctly. If you're really looking for object equivalence, you already know about Object.is, and you can just use it. I would even argue that, since most people aren't experts in IEEE754, they will accidentally feel the need to treat -0 and 0 differently when they actually don't want to do so. There will be special cases, like memoization, but multiplying numbers is more common that writing memoization tools.

If someone had a use case for the recursive "are these IEEE754/mathematically the same" semantics, that might convince me otherwise on this question. My current intuition is, mathematical comparisons in these contexts is just a footgun, not the intended semantics at usage sites.

Like the example shown above twice, the intuition of most programmers will likely disagree with your intuition here, especially those coming from other languages with these kind of structures. I think the code that was posted not working would be a major major major footgun.

I'm not sure how you'd all weigh this objective, but one goal of this proposal is to permit implementations to optimize ===, taking advantage of how the structures will never change. But if === is an operation on an equivalence class of objects, such an optimization through techniques like "hash consing" (reusing the same structure if the contents are the same, so === is cheap if they are the same) become impractical/impossible. (Aside: Not all engines will do this optimization, though, and it's likely that it sometimes won't kick in even on engines that do perform it. Ultimately, the situation would be similar to strings, where only some engines optimize with rope data structures internally, and they differ in their heuristics.)

Yes, -0 and NaN would make this more complex, but I suspect not by much. An implementation will most likely have a slow path when the two structures are not reference equal where it can apply other checks. Note that this doesn't have to literally be recursing through the structures, you can take advantage of known shapes and whatnot to skip that. There are a lot of very fast languages with tuple equality we can take notes from.

(I'd be OK, I guess, with normalizing -0 to 0--it seems like the least harmful option in this thread--but I still don't really understand the motivation, and it seems a little unfortunate to sort of randomly lose the ability to represent -0 within a Record/Tuple. So I agree with @bakkot 's comments at the start of this thread)

As I said above, normalizing -0 to 0 is incorrect because it can cause operations involving very small or very large numbers to end up with the wrong sign.

bakkot

comment created time in 2 days

Pull request review commentnodejs/node

lib: initial experimental AbortController implementation

+'use strict';++// Modeled very closely on the AbortController implementation+// in https://github.com/mysticatea/abort-controller (MIT license)++const {+  SafeWeakMap,+  Object,+  Symbol,+} = primordials;+const EventEmitter = require('events');+const {+  codes: { ERR_INVALID_THIS }+} = require('internal/errors');++const signals = new SafeWeakMap();+const controllers = new SafeWeakMap();++class AbortSignal extends EventEmitter {

There was a plan to standardize the interface here: https://github.com/tc39/proposal-cancellation

jasnell

comment created time in 2 days

pull request commentnodejs/node

src: use NewFromUtf8Literal in GetLinkedBinding

I wonder if we could also change those FIXED string macros

danbev

comment created time in 2 days

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

I don't think "best" has anything to do with this. You can either compare them correctly or incorrectly.

bakkot

comment created time in 3 days

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

@bakkot i mean the part about zeros... sets/maps are a weird category because they deduplicate their keys. most set/map impls in languages either don't specialize for 0 and use whichever one is inserted first (like c++) or provide no default hashing implementation for doubles (like rust) but js chose to normalize it to +0. I don't think you can really take any useful conclusion for "how to store a property" from that.

Aside from maps/sets, it has been pointed out multiple times that treating normalizing or doing weird equality things to -0 is mathematically incorrect with regard to how ieee754 works.

bakkot

comment created time in 3 days

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

Did you all just skip my comment or something?

bakkot

comment created time in 3 days

issue commenttc39/proposal-record-tuple

Equality semantics for `-0` and `NaN`

I see in the update slides that -0 and +0 are still being considered not equal and I want to reiterate how incorrect that is. When a negative number underflows to 0 it has to keep its sign or further values extrapolated from that number will have the incorrect sign (this is also why normalizing the value to +0 is not correct). Due to this property, IEEE 754 punts sign normalization to equality, which @Zarel helpfully demonstrated above:

As an example, what if someone uses a record/tuple as a coordinate?

const coord = #{x: 0, y: 3};

And then they decide to move it around a bit:

const coord2 = #{x: coord.x * -4, y: coord.y - 3};
const isAtOrigin = coord2 === #{x: 0, y: 0};

isAtOrigin would be false, but I think most programmers writing code like this would assume it would be true, and if they did, they'd encounter no problems other than this specific comparison.

As for NaN, it doesn't break any calculation you might be doing to make it equal to itself (although it is against IEEE 754 to do so, and some people will argue that preventing that equality can halt forward progress as NaN intends), but as I mentioned above, I think breaking programmer's expectations about recursive equality is far more harmful than the benefit of being able to compare NaN (I was unable to find a single person who thought that non-recursive equality was a good idea, and many were surprised that such a question would even need to be asked).

bakkot

comment created time in 4 days

issue commentnodejs/modules

Cancellation and ESM?

I don't think cancellation fits into module loading very well, at least because racing a successful import being cached with being cancelled could end up confusing someone.

benjamingr

comment created time in 4 days

issue commentopenjs-foundation/standards

Discuss foundation TC39 delegate expectations

So as this currently stands, how do we discuss potentially blocking a proposal?

ljharb

comment created time in 4 days

issue closedtc39/proposal-iterator-helpers

Definition of "product" in prior art

In the prior art comparison, it's cited that both Rust and Python implement product.

The definition of product in those cases are very different:

Mixing those concepts defeats the purpose of the comparison table, in my opinion, as the ES iterators helpers could contain either or both.

closed time in 5 days

leopiccionia

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems whether the loader is shared or not is not exposed, you just get an object with the relevant hook functions to call.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems in my mind:

import { createLoader } from 'node api';

// whether http-loader is in this thread or another thread or whatever is not exposed
const httpLoader = await createLoader('http-loader');

export function resolve(whatever) {
  if (whatever needs http loader) {
    return httpLoader.resolve(whatever);
  }
}
jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

I'd be interested in discussing this in more detail because I don't think having both precludes your use case.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems this is the first i've heard of such a thing. i assume we would then provide some first class api which allows handling loaders without worrying about details that node should handle.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

a userland package that orchestrates multiple loaders

Why would such a thing exist? Node should be handling this.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems i think the loaders say whether they are shared or not, you just pass --loader x --loader y like normal.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems i don't understand at all why allowing this means loaders can't be composed. if a resolve hook can run in another thread in can run in the main thread.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems you shouldn't be able to chain the result of hooks which create actual module instances, regardless of where they run, there's no composition you can do at that point.

jkrems

comment created time in 5 days

pull request commentnodejs/node

doc: merge CJS and ESM docs

Splitting it into separate commits might help. We will also need some sort of redirect from esm.html which preserves the # fragment.

aduh95

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems i don't think it makes that much complexity, aside from having to choose where the loader you're writing runs. from the perspective of the loader it's just a bunch of loader.resolveOrWhatever calls which might communicate with a worker thread or call a function directly.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems i don't object to shared loaders, but i'm not a fan of removing unshared loaders.

jkrems

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

@jkrems well it is a bit more complex, you're generally working with live values, for example webassembly instances, a kind of data you might want to expose as an es module, can't be transferred.

jkrems

comment created time in 5 days

pull request commentnodejs/node

[WIP] src,lib: policy permissions

I'm also more of a fan of the approach Guy mentioned, it would be interesting to explore more OCAP within node.

jasnell

comment created time in 5 days

issue commenttc39/proposal-iterator-helpers

Definition of 'prelude steps' for generator function algorithms

Sorry for not noticing this issue. What I'm working with at the moment looks like this:

I'm hoping it is the final iteration but I'm not sure, as Jason says we will be discussing it during the upcoming plenary.

avandolder

comment created time in 5 days

pull request commentnodejs/node

module: remove dynamicInstantiate loader hook

I'd like us to have some definitive way of creating modules from data (not transformed code) that doesn't require generating javascript source text.

jkrems

comment created time in 5 days

PR closed nodejs/node

`make -j4 test` (UNIX), or `vcbuild test` (Windows)

<!-- Thank you for your pull request. Please provide a description above and review the requirements below.

Bug fixes and new features should include tests and possibly benchmarks.

Contributors guide: https://github.com/nodejs/node/blob/master/CONTRIBUTING.md -->

Checklist

<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

  • [x] make -j4 test (UNIX), or vcbuild test (Windows) passes
  • [x] tests and/or benchmarks are included
  • [x] documentation is changed or added
  • [x] commit message follows commit guidelines

<!-- Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or

(b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or

(c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it.

(d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. -->

+125 -150

0 comment

7 changed files

ynppny

pr closed time in 6 days

delete branch nodejs/node

delete branch : Travis-test-Py36-or-Py37

delete time in 6 days

delete branch nodejs/node

delete branch : v13.14.0-proposal

delete time in 6 days

Pull request review commentnodejs/node

module: remove dynamicInstantiate loader hook

 import module from 'module'; -export function getFormat(url, context, defaultGetFormat) {-  if (module.builtinModules.includes(url)) {+const GET_BUILTIN = `$__get_builtin_hole_${Date.now()}`;++export function getGlobalPreloadCode() {+  return `Object.defineProperty(globalThis, ${JSON.stringify(GET_BUILTIN)}, {+  value: (builtinName) => {+    return getBuiltin(builtinName);+  },+  enumerable: false,+  configurable: false,+});+`;+}++export function resolve(specifier, context, defaultResolve) {+  const def = defaultResolve(specifier, context);+  if (def.url.startsWith('nodejs:')) {+    return {+      url: `custom-${def.url}`,+    };+  }+  return def;+}++export function getSource(url, context, defaultGetSource) {+  if (url.startsWith('custom-nodejs:')) {+    const urlObj = new URL(url);     return {-      format: 'dynamic'+      source: generateBuiltinModule(urlObj.pathname),+      format: 'module',     };   }+  return defaultGetSource(url, context);+}++export function getFormat(url, context, defaultGetFormat) {+  if (url.startsWith('custom-nodejs:')) {+    return { format: 'module' };+  }   return defaultGetFormat(url, context, defaultGetFormat); } -export function dynamicInstantiate(url) {-  const builtinInstance = module._load(url);-  const builtinExports = ['default', ...Object.keys(builtinInstance)];-  return {-    exports: builtinExports,-    execute: exports => {-      for (let name of builtinExports)-        exports[name].set(builtinInstance[name]);-      exports.default.set(builtinInstance);-    }-  };+function generateBuiltinModule(builtinName) {+  const builtinInstance = module._load(builtinName);+  const builtinExports = [+    ...Object.keys(builtinInstance),+  ];+  return `\

this seems horrible enough to constitute figuring out some sort of replacement for dynamicInstantiate

jkrems

comment created time in 6 days

Pull request review commentnodejs/node

module: remove dynamicInstantiate loader hook

 class Loader {     if (resolve !== undefined)       this._resolve = FunctionPrototypeBind(resolve, null);     if (dynamicInstantiate !== undefined) {-      this._dynamicInstantiate =-        FunctionPrototypeBind(dynamicInstantiate, null);+      process.emitWarning(

this isn't needed

jkrems

comment created time in 6 days

pull request commentnodejs/node

cli: support --experimental-top-level-await in NODE_OPTIONS

it is weird to me that we allow experimental options in the env

dfabulich

comment created time in 6 days

delete branch nodejs/node

delete branch : libuv

delete time in 6 days

delete branch nodejs/node

delete branch : doc-update-watermark-comment

delete time in 6 days

pull request commentnodejs/node

errors: print original exception context

@bcoe i think its okay to use the error position. alternatively, you could store the message position info on the error in c++ (like how we store decorations) so its available in the js prepareStackTrace callback.

bcoe

comment created time in 6 days

pull request commentnodejs/node

errors: print original exception context

I'm trying to figure out how it's placing the ^ under the throw, rather than under the Error

As a general rule, v8::Message is generated from the location of throw, and the error's stack is generated from the location of the error. The v8::Message might sometimes point to the error location instead if it failed to figure out the throw location.

bcoe

comment created time in 6 days

issue closedModdable-OpenSource/moddable

fxIsFunction gives wrong result for revoked proxy

const p = Proxy.revocable(function(){}, {});
p.revoke();
print(typeof p.proxy);

should be function, but xs gives object. This happens because xsIsFunction redirects the lookup to proxy.target, but proxy.target is nulled out when the proxy is revoked:

https://github.com/Moddable-OpenSource/moddable/blob/15c572436bdcb355b6222814f6e8300c0f927700/xs/sources/xsFunction.c#L114-L129

I'm not sure how to run js files with the output of the build, but i did come up with this patch:

diff --git a/xs/sources/xsAll.h b/xs/sources/xsAll.h
index 31deeee4..83b2785d 100644
--- a/xs/sources/xsAll.h
+++ b/xs/sources/xsAll.h
@@ -1718,6 +1718,7 @@ enum {
        XS_LEVEL_FLAG = 32,
        XS_DONT_MARSHALL_FLAG = 64,
        /* XS_MARK_FLAG = 128, */
+       XS_PROXY_IS_CALLABLE_FLAG = 256,
 
        /* property flags */
        XS_INTERNAL_FLAG = 1,
diff --git a/xs/sources/xsFunction.c b/xs/sources/xsFunction.c
index b5df3fc5..89f2c4e9 100644
--- a/xs/sources/xsFunction.c
+++ b/xs/sources/xsFunction.c
@@ -113,15 +113,13 @@ txBoolean fxIsCallable(txMachine* the, txSlot* slot)
 
 txBoolean fxIsFunction(txMachine* the, txSlot* instance)
 {
-again:
        if (instance) {
                txSlot* exotic = instance->next;
                if (exotic && (exotic->flag & XS_INTERNAL_FLAG)) {
                        if (((exotic->kind == XS_CALLBACK_KIND) || (exotic->kind == XS_CALLBACK_X_KIND) || (exotic->kind == XS_CODE_KIND) || (exotic->kind == XS_CODE_X_KIND)))
                                return 1;
                        if (exotic->kind == XS_PROXY_KIND) {
-                               instance = exotic->value.proxy.target;
-                               goto again;
+                               return exotic->flag & XS_PROXY_IS_CALLABLE_FLAG;
                        }
                }
        }
diff --git a/xs/sources/xsProxy.c b/xs/sources/xsProxy.c
index 42017094..4227457d 100644
--- a/xs/sources/xsProxy.c
+++ b/xs/sources/xsProxy.c
@@ -825,6 +825,9 @@ void fx_Proxy(txMachine* the)
        if ((handler->next) && (handler->next->kind == XS_PROXY_KIND) && !handler->next->value.proxy.handler)
                mxTypeError("handler is a revoked proxy");
        instance->flag |= target->flag & XS_CAN_CONSTRUCT_FLAG;
+       if (fxIsCallable(the, target)) {
+               instance->flag |= XS_PROXY_IS_CALLABLE_FLAG;
+       }
        proxy->value.proxy.target = target;
        proxy->value.proxy.handler = handler;
 }
@@ -854,6 +857,10 @@ void fx_Proxy_revocable(txMachine* the)
        mxPushUndefined();
        instance = fxNewProxyInstance(the);
        slot = instance->next;
+       instance->flag |= target->flag & XS_CAN_CONSTRUCT_FLAG;
+       if (fxIsCallable(the, target)) {
+               instance->flag |= XS_PROXY_IS_CALLABLE_FLAG;
+       }
        slot->value.proxy.target = target;
        slot->value.proxy.handler = handler;
        property = fxNextSlotProperty(the, property, the->stack, mxID(_proxy), XS_GET_ONLY);

closed time in 6 days

devsnek

issue commentModdable-OpenSource/moddable

fxIsFunction gives wrong result for revoked proxy

This does appear to have been fixed at some point.

devsnek

comment created time in 6 days

pull request commenttc39/ecma262

Editorial: refactor tail calls

@claudepache the branches in EvaluateCall seemed awkward enough that using TailCall there wouldn't be an improvement but I'm happy to change it as well.

devsnek

comment created time in 7 days

pull request commenttc39/ecma262

Editorial: refactor tail calls

@bakkot can you expand on why you don't think this is an improvement? I think it makes the intention of tail call sites clearer and prevents the calls from being split up.

devsnek

comment created time in 7 days

PR opened tc39/ecma262

Editorial: refactor tail calls

<!-- If you are changing the signature or behavior of an existing construct, please check if this affects downstream dependencies (searching for the construct's name is sufficient) and if needed file an issue:

+12 -8

0 comment

1 changed file

pr created time in 7 days

create barnchdevsnek/ecma262

branch : tailcall

created branch time in 7 days

PR closed nodejs/repl

Tab instant completion

Instantly autocomplete a common part of all suggested completions

Example:

Typing "P<Tab>" has two variants of completion: "Proxy" and "Promise", so the console would instantly update to "Pro" as this is a common part of all suggested completions.

The behavior is similar to Bash or ZSH.

Resolves #32

+30 -19

1 comment

1 changed file

bogdan

pr closed time in 7 days

pull request commentnodejs/repl

Tab instant completion

Due to readline migration we have this functionality now

bogdan

comment created time in 7 days

issue commentnodejs/node

Incorrect syntax error message when using `await` in REPL

--experimental-repl-await can only transform code it can parse, so with invalid syntax, it gets passed to the evaluator without being transformed, and then the first thing the evaluator sees is await which isn't valid.

bgmort

comment created time in 7 days

issue commenttc39/proposal-module-attributes

Inline vs out of line module attributes

I really can't see inline as anything except as a confusing burden. Take #58 for example, a seemingly reasonable request is probably impossible because the caching semantics of inline attributes are a mess and anyone trying to use the data will probably end up with odd bugs.

littledan

comment created time in 7 days

Pull request review commentnodejs/node

esm: fix annotations on resolve hook doc snippet

 condition list **must** be passed through to the `defaultResolve` function. ```js /**  * @param {string} specifier- * @param {object} context- * @param {string} context.parentURL- * @param {string[]} context.conditions- * @param {function} defaultResolve- * @returns {object} response- * @returns {string} response.url+ * @param {{+ *   parentURL:!(string|undefined),+ *   conditions:Array<string>,+ * }} context+ * @param {Function} defaultResolve+ * @returns {{url:string}}  */-export async function resolve(specifier, context, defaultResolve) {+export function resolve(specifier, context, defaultResolve) {   const { parentURL = null } = context;-  if (someCondition) {+  if (Math.random()) { // Some condition.     // For some or all specifiers, do some custom logic for resolving.     // Always return an object of the form {url: <string>}     return {-      url: (parentURL) ?-        new URL(specifier, parentURL).href : new URL(specifier).href+      url: parentURL ?+        new URL(specifier, parentURL).href :+        new URL(specifier).href,     };   }-  if (anotherCondition) {-    // When calling the defaultResolve, the arguments can be modified. In this+  if (Math.random()) { // Another condition.+    // When calling `defaultResolve`, the arguments can be modified. In this     // case it's adding another value for matching conditional exports.     return defaultResolve(specifier, {       ...context,-      conditions: [...context.conditions, 'another-condition'],+      conditions: context.conditions.concat(['another-condition']),

please keep the spread operation here.

DerekNonGeneric

comment created time in 7 days

push eventnodejs/repl

Gus Caplan

commit sha 212f90ef019e46b86cbf44089812a5e8d4794f92

require completion

view details

push time in 7 days

Pull request review commentnodejs/node

repl: simplify internal repl

 changes:   * `completer` {Function} An optional function used for custom Tab auto      completion. See [`readline.InterfaceCompleter`][] for an example.   * `replMode` {symbol} A flag that specifies whether the default evaluator-    executes all JavaScript commands in strict mode or default (sloppy) mode.+    executes all JavaScript commands in strict mode or sloppy mode.     Acceptable values are:     * `repl.REPL_MODE_SLOPPY` to evaluate expressions in sloppy mode.     * `repl.REPL_MODE_STRICT` to evaluate expressions in strict mode. This is-      equivalent to prefacing every repl statement with `'use strict'`.+      equivalent to prefacing every repl statement with `'use strict'` or to+      start the node executable with the `--use-strict` flag. **Default:**

Can you remove the --use-strict check from repl instead of documenting this?

BridgeAR

comment created time in 7 days

push eventnodejs/repl

Gus Caplan

commit sha 1217e44452ea16c8f1b8a83ecc191ea839205414

fix construct completion for js-defined functions

view details

push time in 7 days

push eventnodejs/repl

Gus Caplan

commit sha 33b34411ef3f54e57154cc6f117f2fcecba7e123

dedupe annotations

view details

push time in 7 days

push eventnodejs/repl

Gus Caplan

commit sha 8271bfbd760ac300f71a23d4b4b848e5a0979e71

some small changes

view details

Gus Caplan

commit sha e85c323af8328bbcee2a4929b1c4df8546f486ee

rewrite

view details

push time in 7 days

PR opened microsoft/TypeScript

Add missing properties to stdlib

<!-- Thank you for submitting a pull request!

Please verify that:

  • [ ] There is an associated issue in the Backlog milestone (required)
  • [x] Code is up-to-date with the master branch
  • [x] You've successfully run gulp runtests locally
  • [ ] There are new or updated unit tests validating the change

Refer to CONTRIBUTING.MD for more details. https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md -->

Fixes #38676 Fixes #38677

+6 -0

0 comment

2 changed files

pr created time in 7 days

issue openedmicrosoft/TypeScript

Symbol.prototype[Symbol.toPrimitive] missing

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a bug, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:

  • Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  • Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the entire template below. -->

<!-- Please try to reproduce the issue with the latest published version. It may have already been fixed. For npm: typescript@next This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly --> TypeScript Version: 3.9.2

<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms:

Code

Symbol.prototype[Symbol.toPrimitive]

Expected behavior: is typed as relevant function

Actual behavior: doesn't exist, typed as any

Playground Link: <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior -->

Related Issues: <!-- Did you find other bugs that looked similar? -->

created time in 7 days

issue openedmicrosoft/TypeScript

DataView.prototype missing

<!-- 🚨 STOP 🚨 𝗦𝗧𝗢𝗣 🚨 𝑺𝑻𝑶𝑷 🚨

Half of all issues filed here are duplicates, answered in the FAQ, or not appropriate for the bug tracker. Even if you think you've found a bug, please read the FAQ first, especially the Common "Bugs" That Aren't Bugs section!

Please help us by doing the following steps before logging an issue:

  • Search: https://github.com/Microsoft/TypeScript/search?type=Issues
  • Read the FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ

Please fill in the entire template below. -->

<!-- Please try to reproduce the issue with the latest published version. It may have already been fixed. For npm: typescript@next This is also the 'Nightly' version in the playground: http://www.typescriptlang.org/play/?ts=Nightly --> TypeScript Version: 3.9.2

<!-- Search terms you tried before logging this (so others can find this issue more easily) --> Search Terms:

Code

DataView.prototype

Expected behavior: is DataView.prototype

Actual behavior: is Function.prototype

Playground Link: <!-- A link to a TypeScript Playground "Share" link which demonstrates this behavior -->

https://www.typescriptlang.org/play/?target=99#code/CIQwLiBqCWCmDuA6ADgJwPZkwT2bRA5rGAKrQB2YAHEA

Related Issues: <!-- Did you find other bugs that looked similar? -->

created time in 7 days

create barnchdevsnek/TypeScript

branch : dataviewprototype

created branch time in 7 days

fork devsnek/TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

https://www.typescriptlang.org

fork in 7 days

Pull request review commentnodejs/node

doc: Mention --experimental-top-level-await flag

 including the autocompleted part. Pressing `<escape>` cancels that behavior.  #### Support for Top-Level Await -It's now possible to use the await keyword outside of async functions.+It's now possible to use the await keyword outside of async functions, with the `--experimental-top-level-await` flag.

we would not like to recommend that people use harmony flags

dfabulich

comment created time in 7 days

pull request commentnodejs/node

doc: Mention --experimental-top-level-await flag

this will also require a change to https://github.com/nodejs/nodejs.org/blob/master/locale/en/blog/release/v14.3.0.md

dfabulich

comment created time in 7 days

issue commentnodejs/node

Top-level await throws SyntaxError

@jsejcksn some example issues: #31410, #31447. i don't know what the release notes will say, i don't write them.

jsejcksn

comment created time in 7 days

issue commentnodejs/node

Top-level await throws SyntaxError

@jsejcksn it didn't work properly with the harmony flag before 14.3.0. Now with the flag it works correctly.

jsejcksn

comment created time in 7 days

issue closednodejs/node

Top-level await throws SyntaxError

  • Version: v14.3.0
  • Platform: Darwin hostname 19.4.0 Darwin Kernel Version 19.4.0: Wed Mar 4 22:28:40 PST 2020; root:xnu-6153.101.6~15/RELEASE_X86_64 x86_64

What steps will reproduce the bug?

  1. Create index.mjs:
const wait = async (ms, value) => new Promise(res => setTimeout(() => res(value), ms));

const value = await wait(100, 'hello world');
console.log(value);
  1. Run node index.mjs

How often does it reproduce? Is there a required condition?

100%

What is the expected behavior?

hello world will be logged to console after ~100ms

What do you see instead?

file:///index.mjs:3
const value = await wait(100, 'hello world');
              ^^^^^

SyntaxError: Unexpected reserved word
    at Loader.moduleStrategy (internal/modules/esm/translators.js:88:18)
    at async link (internal/modules/esm/module_job.js:41:21)

and if I rename index.mjs to index.cjs:

/index.cjs:3
const value = await wait(100, 'hello world');
              ^^^^^

SyntaxError: await is only valid in async function
    at wrapSafe (internal/modules/cjs/loader.js:1116:16)
    at Module._compile (internal/modules/cjs/loader.js:1164:27)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1220:10)
    at Module.load (internal/modules/cjs/loader.js:1049:32)
    at Function.Module._load (internal/modules/cjs/loader.js:937:14)
    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
    at internal/main/run_main_module.js:17:47

Additional information

From the release notes for v14.3.0:

Support for Top-Level Await

It's now possible to use the await keyword outside of async functions.

Did I misinterpret the release notes? Is the CLI argument --harmony-top-level-await still required for TLA?

closed time in 8 days

jsejcksn
more