static njs_int_t
-njs_function_arguments_thrower(njs_vm_t *vm, njs_value_t *value,
- njs_value_t *setval, njs_value_t *retval)
+njs_function_prototype_thrower(njs_vm_t *vm, njs_value_t *args,
+ njs_uint_t nargs, njs_index_t unused)
{
- njs_type_error(vm, "\"caller\", \"callee\" properties may not be accessed");
+ njs_type_error(vm, "\"caller\", \"callee\", \"arguments\" "
+ "properties may not be accessed");
return NJS_ERROR;
}
const njs_object_prop_t njs_arguments_object_instance_properties[] =
{
{
- .type = NJS_PROPERTY_HANDLER,
- .name = njs_string("caller"),
- .value = njs_prop_handler(njs_function_arguments_thrower),
- },
-
- {
- .type = NJS_PROPERTY_HANDLER,
+ .type = NJS_PROPERTY,
.name = njs_string("callee"),
- .value = njs_prop_handler(njs_function_arguments_thrower),
+ .value = njs_value(NJS_INVALID, 1, NAN),
+ .getter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+ .setter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+ .writable = NJS_ATTRIBUTE_UNSET,
},
};
.writable = 1,
.configurable = 1,
},
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("caller"),
+ .value = njs_value(NJS_INVALID, 1, NAN),
+ .getter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+ .setter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+ .writable = NJS_ATTRIBUTE_UNSET,
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("arguments"),
+ .value = njs_value(NJS_INVALID, 1, NAN),
+ .getter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+ .setter = njs_native_function(njs_function_prototype_thrower, 0, 0),
+ .writable = NJS_ATTRIBUTE_UNSET,
+ .configurable = 1,
+ },
};
{ njs_str("(function(){return arguments[3];}).bind(null, 0)('a','b','c')"),
njs_str("c") },
- { njs_str("(function(){return arguments.callee;})()"),
- njs_str("TypeError: \"caller\", \"callee\" properties may not be accessed") },
-
- { njs_str("(function(){return arguments.caller;})()"),
- njs_str("TypeError: \"caller\", \"callee\" properties may not be accessed") },
-
{ njs_str("function sum() { var args = Array.prototype.slice.call(arguments); "
"return args.reduce(function(prev, curr) {return prev + curr})};"
"[sum(1), sum(1,2), sum(1,2,3), sum(1,2,3,4)]"),
"[concat('.',1,2,3), concat('+',1,2,3,4)]"),
njs_str("1.2.3,1+2+3+4") },
+ /* strict mode restrictions */
+
+ { njs_str("(function() {}).caller"),
+ njs_str("TypeError: \"caller\", \"callee\", \"arguments\" properties may not be accessed") },
+
+ { njs_str("(function() {}).arguments"),
+ njs_str("TypeError: \"caller\", \"callee\", \"arguments\" properties may not be accessed") },
+
+ { njs_str("var p = Object.getPrototypeOf(function() {});"
+ "var d = Object.getOwnPropertyDescriptor(p, 'caller');"
+ "typeof d.get == 'function' && typeof d.get == typeof d.set"
+ " && d.configurable && !d.enumerable"),
+ njs_str("true") },
+
+ { njs_str("var p = Object.getPrototypeOf(function() {});"
+ "var d = Object.getOwnPropertyDescriptor(p, 'arguments');"
+ "typeof d.get == 'function' && typeof d.get == typeof d.set"
+ " && d.configurable && !d.enumerable"),
+ njs_str("true") },
+
+ { njs_str("(function(){return arguments.callee;})()"),
+ njs_str("TypeError: \"caller\", \"callee\", \"arguments\" properties may not be accessed") },
+
+ { njs_str("var f = function() { return arguments; };"
+ "Object.getOwnPropertyDescriptor(f(), 'caller')"),
+ njs_str("undefined") },
+
+ { njs_str("var f = function() { return arguments; };"
+ "var d = Object.getOwnPropertyDescriptor(f(), 'callee');"
+ "typeof d.get == 'function' && typeof d.get == typeof d.set"
+ " && !d.configurable && !d.enumerable"),
+ njs_str("true") },
+
/* rest parameters. */
{ njs_str("function myFoo(a,b,...other) { return other };"
"function isConfigurableMethods(o) {"
" var except = ["
" 'prototype',"
+ " 'caller',"
+ " 'arguments',"
" ];"
" return Object.getOwnPropertyNames(o)"
" .filter(v => !except.includes(v)"
"function isWritableMethods(o) {"
" var except = ["
" 'prototype',"
+ " 'caller',"
+ " 'arguments',"
" ];"
" return Object.getOwnPropertyNames(o)"
" .filter(v => !except.includes(v)"
" var except = ["
" 'prototype',"
" 'constructor',"
+ " 'caller',"
+ " 'arguments',"
" ];"
" return Object.getOwnPropertyNames(o)"
" .filter(v => !except.includes(v)"