}
prop = lhq.value;
+
+ if (prop->type == NJS_WHITEOUT) {
+ state->index++;
+ break;
+ }
+
state->prop_value = &prop->value;
if (njs_json_is_non_empty(&prop->value)) {
if (!prop->enumerable
|| njs_is_void(&prop->value)
+ || !njs_is_valid(&prop->value)
|| njs_is_function(&prop->value))
{
break;
prop = lhq.value;
val = &prop->value;
- if (!prop->enumerable) {
+ if (prop->type == NJS_WHITEOUT || !prop->enumerable) {
break;
}
}
break;
}
- if (prop->enumerable) {
+ if (prop->type != NJS_WHITEOUT && prop->enumerable) {
keys_length++;
}
}
break;
}
- if (prop->enumerable) {
+ if (prop->type != NJS_WHITEOUT && prop->enumerable) {
njs_string_copy(&keys->start[n++], &prop->name);
}
}
return NXT_ERROR;
}
+ if (nxt_slow_path(pq.lhq.value != NULL)) {
+ prop = pq.lhq.value;
+
+ if (nxt_slow_path(prop->type == NJS_WHITEOUT)) {
+ /* Previously deleted property. */
+ prop->type = NJS_PROPERTY;
+ prop->enumerable = 1;
+ prop->configurable = 1;
+ prop->writable = 1;
+ break;
+ }
+ }
+
prop = njs_object_prop_alloc(vm, &pq.value, &njs_value_void, 1);
if (nxt_slow_path(prop == NULL)) {
return NXT_ERROR;
return NXT_ERROR;
}
- pq.lhq.pool = vm->mem_cache_pool;
-
- (void) nxt_lvlhsh_delete(&object->data.u.object->hash, &pq.lhq);
-
- njs_release(vm, property);
+ /* GC: release value. */
+ prop->type = NJS_WHITEOUT;
+ njs_set_invalid(&prop->value);
retval = &njs_value_true;
break;
}
- if (prop->enumerable) {
+ if (prop->type != NJS_WHITEOUT && prop->enumerable) {
*retval = prop->name;
return code->offset;
"for (var p in o) {s += p}; s"),
nxt_string("y") },
+ { nxt_string("var o = {a:1, b:2}; var arr = []; "
+ "for (var a in o) {arr.push(a)}; arr"),
+ nxt_string("a,b") },
+
+ { nxt_string("var o = {a:1, b:2}; var arr = []; delete o.a; "
+ "for (var a in o) {arr.push(a)}; arr"),
+ nxt_string("b") },
+
/* switch. */
{ nxt_string("switch"),
{ nxt_string("delete --[][1]"),
nxt_string("true") },
+ { nxt_string("var a = [1,2]; delete a.length"),
+ nxt_string("false") },
+
{ nxt_string("var a = [1,2,3]; a.x = 10; delete a[1]"),
nxt_string("true") },
{ nxt_string("Math.E = 1"),
nxt_string("TypeError: Cannot assign to read-only property 'E' of object") },
+ { nxt_string("var o = { 'a': 1, 'b': 2 }; var i; "
+ "for (i in o) { delete o.a; delete o.b; }; njs.dump(o)"),
+ nxt_string("{}") },
+
+ { nxt_string("var o = {}; Object.defineProperty(o, 'a', {value:1, configurable:1}); "
+ "delete o.a; o.a=2; o.a"),
+ nxt_string("2") },
+
{ nxt_string("var a = {}; 1 in a"),
nxt_string("false") },
{ nxt_string("var a = [,6,,3]; a.one = 7; Object.keys(a)"),
nxt_string("1,3,one") },
+ { nxt_string("var o = {a:1,b:2}; delete o.a; Object.keys(o)"),
+ nxt_string("b") },
+
{ nxt_string("Object.keys()"),
nxt_string("TypeError: cannot convert void argument to object") },