}
+static njs_int_t
+njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
+ njs_index_t unused)
+{
+ uint32_t i, j, length;
+ njs_int_t ret;
+ njs_array_t *names;
+ njs_value_t *key, *source, *value, setval;
+ njs_object_prop_t *prop;
+ njs_property_query_t pq;
+
+ value = njs_arg(args, nargs, 1);
+
+ ret = njs_value_to_object(vm, value);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ for (i = 2; i < nargs; i++) {
+ source = &args[i];
+
+ names = njs_value_own_enumerate(vm, source, NJS_ENUM_KEYS, 1);
+ if (njs_slow_path(names == NULL)) {
+ return NJS_ERROR;
+ }
+
+ length = names->length;
+
+ for (j = 0; j < length; j++) {
+ key = &names->start[j];
+
+ njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1);
+
+ ret = njs_property_query(vm, &pq, source, key);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ prop = pq.lhq.value;
+ if (!prop->enumerable) {
+ continue;
+ }
+
+ ret = njs_value_property(vm, source, key, &setval);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_value_property_set(vm, value, key, &setval);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+ }
+ }
+
+ vm->retval = *value;
+
+ return NJS_OK;
+}
+
+
/*
* The __proto__ property of booleans, numbers and strings primitives,
* of objects created by Boolean(), Number(), and String() constructors,
.writable = 1,
.configurable = 1,
},
+
+ /* Object.assign(). */
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("assign"),
+ .value = njs_native_function(njs_object_assign, 2),
+ .writable = 1,
+ .configurable = 1,
+ },
};
{ njs_str("export"),
njs_str("SyntaxError: Illegal export statement in 1") },
+ { njs_str("Object.assign(undefined)"),
+ njs_str("TypeError: cannot convert null or undefined to object") },
+
+ { njs_str("Object.assign(null)"),
+ njs_str("TypeError: cannot convert null or undefined to object") },
+
+ { njs_str("Object.assign({x:123}).toString()"),
+ njs_str("[object Object]") },
+
+ { njs_str("Object.assign({x:123}).x"),
+ njs_str("123") },
+
+ { njs_str("Object.assign(true)"),
+ njs_str("true") },
+
+ { njs_str("Object.assign(123)"),
+ njs_str("123") },
+
+ { njs_str("var o1 = {a:1, b:1, c:1}; var o2 = {b:2, c:2}; "
+ "var o3 = {c:3}; var obj = Object.assign({}, o1, o2, o3); "
+ "Object.values(obj);"),
+ njs_str("1,2,3") },
+
+ { njs_str("var v1 = 'abc'; var v2 = true; var v3 = 10; "
+ "var obj = Object.assign({}, v1, null, v2, undefined, v3); "
+ "Object.values(obj);"),
+ njs_str("a,b,c") },
+
+ { njs_str("Object.assign(true, {a:123})"),
+ njs_str("true") },
+
+ { njs_str("Object.assign(true, {a:123}).a"),
+ njs_str("123") },
+
+ { njs_str("var y = Object.create({s:123}); y.z = 456;"
+ "Object.assign({}, y).s;"),
+ njs_str("undefined") },
+
+ { njs_str("var obj = {s:123}; Object.defineProperty(obj,"
+ "'p1', {value:12, enumerable:false});"
+ "Object.assign({}, obj).p1"),
+ njs_str("undefined") },
+
+ { njs_str("var obj = {s:123}; Object.defineProperty(obj,"
+ "'x', {value:12, writable:false});"
+ "Object.assign(obj, {x:4})"),
+ njs_str("TypeError: Cannot assign to read-only property \"x\" of object") },
+
+ { njs_str("var obj = {foo:1, get bar() {return 2;}};"
+ "var copy = Object.assign({}, obj);"
+ "Object.getOwnPropertyDescriptor(copy, 'bar').get"),
+ njs_str("undefined") },
+
+ { njs_str("try{var x = Object.defineProperty({}, 'foo',"
+ "{value:1, writable:false});"
+ "Object.assign(x, {bar:2}, {foo:2});}catch(error){};"
+ "x.bar"),
+ njs_str("2") },
+
+ { njs_str("var a = Object.defineProperty({}, 'a',"
+ "{get(){Object.defineProperty(this, 'b',"
+ "{value:2,enumerable:false});"
+ "return 1}, enumerable:1}); a.b =1;"
+ "var x = Object.assign({}, a);x.b;"),
+ njs_str("undefined") },
};