author | Tom Schuster <evilpies@gmail.com> |
Thu, 02 Jul 2015 22:46:19 +0200 | |
changeset 251192 | 1d3fa54d5eb9fbc88c8e4f92bbf3ade5cb426f1f |
parent 251191 | ee6ec5804e11c7d96c7dbf8fa17be42edd374433 |
child 251193 | 63da57eefeeb192ae5a2daa214d0c699e5072eb1 |
push id | 61789 |
push user | evilpies@gmail.com |
push date | Thu, 02 Jul 2015 20:46:36 +0000 |
treeherder | mozilla-inbound@1d3fa54d5eb9 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | efaust |
bugs | 1171053 |
milestone | 42.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
js/src/jsapi-tests/moz.build | file | annotate | diff | comparison | revisions | |
js/src/jsapi-tests/testBindCallable.cpp | file | annotate | diff | comparison | revisions | |
js/src/jsapi.cpp | file | annotate | diff | comparison | revisions | |
js/src/jsapi.h | file | annotate | diff | comparison | revisions | |
js/src/jsfun.cpp | file | annotate | diff | comparison | revisions | |
js/src/jsfun.h | file | annotate | diff | comparison | revisions |
--- a/js/src/jsapi-tests/moz.build +++ b/js/src/jsapi-tests/moz.build @@ -7,17 +7,16 @@ GeckoProgram('jsapi-tests', linkage=None) UNIFIED_SOURCES += [ 'selfTest.cpp', 'testAddPropertyPropcache.cpp', 'testArgumentsObject.cpp', 'testArrayBuffer.cpp', 'testArrayBufferView.cpp', - 'testBindCallable.cpp', 'testBug604087.cpp', 'testCallNonGenericMethodOnProxy.cpp', 'testChromeBuffer.cpp', 'testClassGetter.cpp', 'testCloneScript.cpp', 'testContexts.cpp', 'testDebugger.cpp', 'testDeepFreeze.cpp',
deleted file mode 100644 --- a/js/src/jsapi-tests/testBindCallable.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "jsapi-tests/tests.h" - -BEGIN_TEST(test_BindCallable) -{ - JS::RootedValue v(cx); - EVAL("({ somename : 1717 })", &v); - CHECK(v.isObject()); - - JS::RootedValue func(cx); - EVAL("(function() { return this.somename; })", &func); - CHECK(func.isObject()); - - JS::RootedObject funcObj(cx, func.toObjectOrNull()); - JS::RootedObject vObj(cx, v.toObjectOrNull()); - JSObject* newCallable = JS_BindCallable(cx, funcObj, vObj); - CHECK(newCallable); - - JS::RootedValue retval(cx); - JS::RootedValue fun(cx, JS::ObjectValue(*newCallable)); - bool called = JS_CallFunctionValue(cx, nullptr, fun, JS::HandleValueArray::empty(), &retval); - CHECK(called); - - CHECK(retval.isInt32()); - - CHECK(retval.toInt32() == 1717); - return true; -} -END_TEST(test_BindCallable)
--- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -3491,23 +3491,16 @@ JS_IsNativeFunction(JSObject* funobj, JS } extern JS_PUBLIC_API(bool) JS_IsConstructor(JSFunction* fun) { return fun->isConstructor(); } -JS_PUBLIC_API(JSObject*) -JS_BindCallable(JSContext* cx, HandleObject target, HandleObject newThis) -{ - RootedValue thisArg(cx, ObjectValue(*newThis)); - return fun_bind(cx, target, thisArg, nullptr, 0); -} - static bool GenericNativeMethodDispatcher(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); const JSFunctionSpec* fs = (JSFunctionSpec*) args.callee().as<JSFunction>().getExtendedSlot(0).toPrivate(); MOZ_ASSERT((fs->flags & JSFUN_GENERIC_NATIVE) != 0);
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -3275,24 +3275,16 @@ JS_ObjectIsFunction(JSContext* cx, JSObj extern JS_PUBLIC_API(bool) JS_IsNativeFunction(JSObject* funobj, JSNative call); /* Return whether the given function is a valid constructor. */ extern JS_PUBLIC_API(bool) JS_IsConstructor(JSFunction* fun); -/* - * Bind the given callable to use the given object as "this". - * - * If |callable| is not callable, will throw and return nullptr. - */ -extern JS_PUBLIC_API(JSObject*) -JS_BindCallable(JSContext* cx, JS::Handle<JSObject*> callable, JS::Handle<JSObject*> newThis); - // This enum is used to select if properties with JSPROP_DEFINE_LATE flag // should be defined on the object. // Normal JSAPI consumers probably always want DefineAllProperties here. enum PropertyDefinitionBehavior { DefineAllProperties, OnlyDefineLateProperties, DontDefineLateProperties };
--- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1581,107 +1581,96 @@ js::fun_bind(JSContext* cx, unsigned arg // Step 3. Value* boundArgs = nullptr; unsigned argslen = 0; if (args.length() > 1) { boundArgs = args.array() + 1; argslen = args.length() - 1; } - // Steps 4-14. RootedValue thisArg(cx, args.length() >= 1 ? args[0] : UndefinedValue()); RootedObject target(cx, &thisv.toObject()); - JSObject* boundFunction = fun_bind(cx, target, thisArg, boundArgs, argslen); - if (!boundFunction) - return false; - // Step 15. - args.rval().setObject(*boundFunction); - return true; -} - -JSObject* -js::fun_bind(JSContext* cx, HandleObject target, HandleValue thisArg, - Value* boundArgs, unsigned argslen) -{ double length = 0.0; // Try to avoid invoking the resolve hook. if (target->is<JSFunction>() && !target->as<JSFunction>().hasResolvedLength()) { uint16_t len; if (!target->as<JSFunction>().getLength(cx, &len)) - return nullptr; + return false; length = Max(0.0, double(len) - argslen); } else { // Steps 5-6. RootedId id(cx, NameToId(cx->names().length)); bool hasLength; if (!HasOwnProperty(cx, target, id, &hasLength)) - return nullptr; + return false; // Step 7-8. if (hasLength) { // a-b. RootedValue targetLen(cx); if (!GetProperty(cx, target, target, id, &targetLen)) - return nullptr; + return false; // d. if (targetLen.isNumber()) length = Max(0.0, JS::ToInteger(targetLen.toNumber()) - argslen); } } RootedString name(cx, cx->names().empty); if (target->is<JSFunction>() && !target->as<JSFunction>().hasResolvedName()) { if (target->as<JSFunction>().atom()) name = target->as<JSFunction>().atom(); } else { // Steps 11-12. RootedValue targetName(cx); if (!GetProperty(cx, target, target, cx->names().name, &targetName)) - return nullptr; + return false; // Step 13. if (targetName.isString()) name = targetName.toString(); } // Step 14. Relevant bits from SetFunctionName. StringBuffer sb(cx); // Disabled for B2G failures. // if (!sb.append("bound ") || !sb.append(name)) - // return nullptr; + // return false; if (!sb.append(name)) - return nullptr; + return false; RootedAtom nameAtom(cx, sb.finishAtom()); if (!nameAtom) - return nullptr; + return false; - // Step 4. + // Step 4. RootedFunction fun(cx, target->isConstructor() ? NewNativeConstructor(cx, CallOrConstructBoundFunction, length, nameAtom) : NewNativeFunction(cx, CallOrConstructBoundFunction, length, nameAtom)); if (!fun) - return nullptr; + return false; if (!fun->initBoundFunction(cx, target, thisArg, boundArgs, argslen)) - return nullptr; + return false; // Steps 9-10. Set length again, because NewNativeFunction/NewNativeConstructor // sometimes truncates. if (length != fun->nargs()) { RootedValue lengthVal(cx, NumberValue(length)); if (!DefineProperty(cx, fun, cx->names().length, lengthVal, nullptr, nullptr, JSPROP_READONLY)) { - return nullptr; + return false; } } - return fun; + // Step 15. + args.rval().setObject(*fun); + return true; } /* * Report "malformed formal parameter" iff no illegal char or similar scanner * error was already reported. */ static bool OnBadFormal(JSContext* cx)
--- a/js/src/jsfun.h +++ b/js/src/jsfun.h @@ -729,20 +729,16 @@ CallOrConstructBoundFunction(JSContext*, extern const JSFunctionSpec function_methods[]; extern bool fun_apply(JSContext* cx, unsigned argc, Value* vp); extern bool fun_call(JSContext* cx, unsigned argc, Value* vp); -extern JSObject* -fun_bind(JSContext* cx, HandleObject target, HandleValue thisArg, - Value* boundArgs, unsigned argslen); - } /* namespace js */ #ifdef DEBUG namespace JS { namespace detail { JS_PUBLIC_API(void) CheckIsValidConstructible(Value calleev);