Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/compiler/test/ts7/baselines/order-parity.json
Original file line number Diff line number Diff line change
Expand Up @@ -10329,6 +10329,12 @@
],
"diags": []
},
"<repo>/tests/corpus/object-inherited-to-string.js": {
"order": [
"<repo>/tests/corpus/object-inherited-to-string.js"
],
"diags": []
},
"<repo>/tests/corpus/object-prototype-identity.mjs": {
"order": [
"<repo>/tests/corpus/object-prototype-identity.mjs"
Expand Down
9 changes: 6 additions & 3 deletions packages/runtime/src/scr_json.c
Original file line number Diff line number Diff line change
Expand Up @@ -8822,10 +8822,13 @@ ScrMap *scr_dyn_native_collection_check(const ScrDyn *value, int map, const char
}

ScrStr *scr_dyn_to_string_method(const ScrDyn *d, const ScrStr *enc, const ScrStr *what) {
if (d->kind == SCR_DYN_FUNC) {
ScrDyn *member = scr_dyn_fn_get(d, "toString", 8);
/* Object.create receivers must run their inherited formatter before the
* default object tag; Effect shard keys use it to produce distinct hashes. */
const bool object_method = d->kind == SCR_DYN_OBJ && scr_dyn_property_owner(d, "toString", 8);
if (d->kind == SCR_DYN_FUNC || object_method) {
ScrDyn *member = object_method ? scr_dyn_obj_read(d, "toString", 8) : scr_dyn_fn_get(d, "toString", 8);
if (scr_exc_pending()) { scr_dyn_release(member); return NULL; }
if (member && member->kind != SCR_DYN_UNDEF) {
if (member && (object_method || member->kind != SCR_DYN_UNDEF)) {
scr_dyn_this_push_dyn(d);
ScrDyn *value = scr_dyn_call(member, NULL, 0, what->data);
scr_dyn_this_pop();
Expand Down
28 changes: 28 additions & 0 deletions tests/corpus/object-inherited-to-string.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const proto = {
toString() { return `value:${this.label}`; }
};
const value = Object.create(proto);
value.label = "first";
const child = Object.create(value);
child.label = "second";
console.log(value.toString(), child.toString(), String(child));
Object.defineProperty(proto, "toString", {
configurable: true,
get() {
const label = this.label;
return function() { return `${label}/${this.label}`; };
}
});
console.log(value.toString(), child.toString());
const shadow = Object.create(value);
Object.defineProperty(shadow, "toString", { value: undefined });
try { shadow.toString(); } catch (error) { console.log(error.name, error.message); }
Object.defineProperty(proto, "toString", {
configurable: true,
get() { throw new Error("formatter getter"); }
});
try { child.toString(); } catch (error) { console.log(error.name, error.message); }
const own = Object.create(null);
own.label = "own";
own.toString = function() { return this.label; };
console.log(own.toString());
9 changes: 9 additions & 0 deletions tests/fixtures/effect4/data-shard-hash.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as ShardId from "effect/cluster/ShardId"
import * as Hash from "effect/Hash"
import * as Equal from "effect/Equal"

const first = ShardId.make("default", 1)
const second = ShardId.make("default", 2)
console.log(first.toString(), second.toString())
console.log(Hash.hash(first), Hash.hash(second), Hash.string("default:1"), Hash.string("default:2"))
console.log(Equal.equals(first, second), Equal.equals(first, ShardId.make("default", 1)))
Loading