diff options
author | Steve Block <steveblock@google.com> | 2009-10-08 17:19:54 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-10-20 00:41:58 +0100 |
commit | 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf (patch) | |
tree | a6c7e2d6cd7bfa7011cc39abbb436142d7a4a7c8 /JavaScriptCore/runtime/JSFunction.cpp | |
parent | e196732677050bd463301566a68a643b6d14b907 (diff) | |
download | external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.zip external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.gz external_webkit-231d4e3152a9c27a73b6ac7badbe6be673aa3ddf.tar.bz2 |
Merge webkit.org at R49305 : Automatic merge by git.
Change-Id: I8968561bc1bfd72b8923b7118d3728579c6dbcc7
Diffstat (limited to 'JavaScriptCore/runtime/JSFunction.cpp')
-rw-r--r-- | JavaScriptCore/runtime/JSFunction.cpp | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/JavaScriptCore/runtime/JSFunction.cpp b/JavaScriptCore/runtime/JSFunction.cpp index 84c6263..024e586 100644 --- a/JavaScriptCore/runtime/JSFunction.cpp +++ b/JavaScriptCore/runtime/JSFunction.cpp @@ -45,12 +45,21 @@ ASSERT_CLASS_FITS_IN_CELL(JSFunction); const ClassInfo JSFunction::info = { "Function", &InternalFunction::info, 0, 0 }; -JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func) +bool JSFunction::isHostFunctionNonInline() const +{ + return isHostFunction(); +} + +JSFunction::JSFunction(NonNullPassRefPtr<Structure> structure) + : Base(structure) + , m_executable(adoptRef(new VPtrHackExecutable())) +{ +} + +JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<Structure> structure, int length, const Identifier& name, NativeFunction func) : Base(&exec->globalData(), structure, name) #if ENABLE(JIT) - , m_body(FunctionBodyNode::createNativeThunk(&exec->globalData())) -#else - , m_body(0) + , m_executable(adoptRef(new NativeExecutable(exec))) #endif { #if ENABLE(JIT) @@ -63,9 +72,9 @@ JSFunction::JSFunction(ExecState* exec, PassRefPtr<Structure> structure, int len #endif } -JSFunction::JSFunction(ExecState* exec, const Identifier& name, FunctionBodyNode* body, ScopeChainNode* scopeChainNode) - : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), name) - , m_body(body) +JSFunction::JSFunction(ExecState* exec, NonNullPassRefPtr<FunctionExecutable> executable, ScopeChainNode* scopeChainNode) + : Base(&exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), executable->name()) + , m_executable(executable) { setScopeChain(scopeChainNode); } @@ -75,20 +84,23 @@ JSFunction::~JSFunction() // JIT code for other functions may have had calls linked directly to the code for this function; these links // are based on a check for the this pointer value for this JSFunction - which will no longer be valid once // this memory is freed and may be reused (potentially for another, different JSFunction). + if (!isHostFunction()) { #if ENABLE(JIT_OPTIMIZE_CALL) - if (m_body && m_body->isGenerated()) - m_body->generatedBytecode().unlinkCallers(); + ASSERT(m_executable); + if (jsExecutable()->isGenerated()) + jsExecutable()->generatedBytecode().unlinkCallers(); #endif - if (!isHostFunction()) scopeChain().~ScopeChain(); // FIXME: Don't we need to do this in the interpreter too? + } } void JSFunction::markChildren(MarkStack& markStack) { Base::markChildren(markStack); - m_body->markAggregate(markStack); - if (!isHostFunction()) + if (!isHostFunction()) { + jsExecutable()->markAggregate(markStack); scopeChain().markAggregate(markStack); + } } CallType JSFunction::getCallData(CallData& callData) @@ -97,7 +109,7 @@ CallType JSFunction::getCallData(CallData& callData) callData.native.function = nativeFunction(); return CallTypeHost; } - callData.js.functionBody = m_body.get(); + callData.js.functionExecutable = jsExecutable(); callData.js.scopeChain = scopeChain().node(); return CallTypeJS; } @@ -105,7 +117,7 @@ CallType JSFunction::getCallData(CallData& callData) JSValue JSFunction::call(ExecState* exec, JSValue thisValue, const ArgList& args) { ASSERT(!isHostFunction()); - return exec->interpreter()->execute(m_body.get(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot()); + return exec->interpreter()->execute(jsExecutable(), exec, this, thisValue.toThisObject(exec), args, scopeChain().node(), exec->exceptionSlot()); } JSValue JSFunction::argumentsGetter(ExecState* exec, const Identifier&, const PropertySlot& slot) @@ -126,7 +138,7 @@ JSValue JSFunction::lengthGetter(ExecState* exec, const Identifier&, const Prope { JSFunction* thisObj = asFunction(slot.slotBase()); ASSERT(!thisObj->isHostFunction()); - return jsNumber(exec, thisObj->m_body->parameterCount()); + return jsNumber(exec, thisObj->jsExecutable()->parameterCount()); } bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) @@ -165,6 +177,35 @@ bool JSFunction::getOwnPropertySlot(ExecState* exec, const Identifier& propertyN return Base::getOwnPropertySlot(exec, propertyName, slot); } + bool JSFunction::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) + { + if (isHostFunction()) + return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); + + if (propertyName == exec->propertyNames().prototype) { + PropertySlot slot; + getOwnPropertySlot(exec, propertyName, slot); + return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); + } + + if (propertyName == exec->propertyNames().arguments) { + descriptor.setDescriptor(exec->interpreter()->retrieveArguments(exec, this), ReadOnly | DontEnum | DontDelete); + return true; + } + + if (propertyName == exec->propertyNames().length) { + descriptor.setDescriptor(jsNumber(exec, jsExecutable()->parameterCount()), ReadOnly | DontEnum | DontDelete); + return true; + } + + if (propertyName == exec->propertyNames().caller) { + descriptor.setDescriptor(exec->interpreter()->retrieveCaller(exec, this), ReadOnly | DontEnum | DontDelete); + return true; + } + + return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); + } + void JSFunction::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { if (isHostFunction()) { @@ -190,7 +231,7 @@ ConstructType JSFunction::getConstructData(ConstructData& constructData) { if (isHostFunction()) return ConstructTypeNone; - constructData.js.functionBody = m_body.get(); + constructData.js.functionExecutable = jsExecutable(); constructData.js.scopeChain = scopeChain().node(); return ConstructTypeJS; } @@ -206,7 +247,7 @@ JSObject* JSFunction::construct(ExecState* exec, const ArgList& args) structure = exec->lexicalGlobalObject()->emptyObjectStructure(); JSObject* thisObj = new (exec) JSObject(structure); - JSValue result = exec->interpreter()->execute(m_body.get(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot()); + JSValue result = exec->interpreter()->execute(jsExecutable(), exec, this, thisObj, args, scopeChain().node(), exec->exceptionSlot()); if (exec->hadException() || !result.isObject()) return thisObj; return asObject(result); |