- stackFrame.globalData->exception = createInvalidParamError(callFrame, "instanceof", baseVal);
- VM_THROW_EXCEPTION_AT_END();
-}
-
-#if ENABLE(DFG_JIT)
-DEFINE_STUB_FUNCTION(void, optimize_from_loop)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- CodeBlock* codeBlock = callFrame->codeBlock();
-
- unsigned bytecodeIndex = stackFrame.args[0].int32();
-
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("%p: Entered optimize_from_loop with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock, codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
-#endif
-
- if (!codeBlock->checkIfOptimizationThresholdReached())
- return;
-
- if (codeBlock->hasOptimizedReplacement()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Considering loop OSR into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
-#endif
- if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Triggering reoptimization of %p(%p) (in loop).\n", codeBlock, codeBlock->replacement());
-#endif
- codeBlock->reoptimize();
- return;
- }
- } else {
- if (!codeBlock->shouldOptimizeNow()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Delaying optimization for %p (in loop) because of insufficient profiling.\n", codeBlock);
-#endif
- return;
- }
-
- ScopeChainNode* scopeChain = callFrame->scopeChain();
-
- JSObject* error = codeBlock->compileOptimized(callFrame, scopeChain);
-#if ENABLE(JIT_VERBOSE_OSR)
- if (error)
- dataLog("WARNING: optimized compilation from loop failed.\n");
-#else
- UNUSED_PARAM(error);
-#endif
-
- if (codeBlock->replacement() == codeBlock) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from loop failed.\n", codeBlock);
-#endif
-
- ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
- codeBlock->dontOptimizeAnytimeSoon();
- return;
- }
- }
-
- CodeBlock* optimizedCodeBlock = codeBlock->replacement();
- ASSERT(optimizedCodeBlock->getJITType() == JITCode::DFGJIT);
-
- if (void* address = DFG::prepareOSREntry(callFrame, optimizedCodeBlock, bytecodeIndex)) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from loop succeeded, performing OSR after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
-#endif
-
- codeBlock->optimizeSoon();
- optimizedCodeBlock->countSpeculationSuccess();
- STUB_SET_RETURN_ADDRESS(address);
- return;
- }
-
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from loop succeeded, OSR failed, after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
-#endif
-
- // Count the OSR failure as a speculation failure. If this happens a lot, then
- // reoptimize.
- optimizedCodeBlock->countSpeculationFailure();
-
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Encountered loop OSR failure into %p(%p) with success/fail %u/%u.\n", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
-#endif
-
- // We are a lot more conservative about triggering reoptimization after OSR failure than
- // before it. If we enter the optimize_from_loop trigger with a bucket full of fail
- // already, then we really would like to reoptimize immediately. But this case covers
- // something else: there weren't many (or any) speculation failures before, but we just
- // failed to enter the speculative code because some variable had the wrong value or
- // because the OSR code decided for any spurious reason that it did not want to OSR
- // right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
- // reoptimization trigger.
- if (optimizedCodeBlock->shouldReoptimizeNow()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Triggering reoptimization of %p(%p) (in loop after OSR fail).\n", codeBlock, codeBlock->replacement());
-#endif
- codeBlock->reoptimize();
- return;
- }
-
- // OSR failed this time, but it might succeed next time! Let the code run a bit
- // longer and then try again.
- codeBlock->optimizeAfterWarmUp();
-}
-
-DEFINE_STUB_FUNCTION(void, optimize_from_ret)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- CodeBlock* codeBlock = callFrame->codeBlock();
-
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Entered optimize_from_ret with executeCounter = %d, reoptimizationRetryCounter = %u, optimizationDelayCounter = %u\n", codeBlock->jitExecuteCounter(), codeBlock->reoptimizationRetryCounter(), codeBlock->optimizationDelayCounter());
-#endif
-
- if (!codeBlock->checkIfOptimizationThresholdReached())
- return;
-
- if (codeBlock->hasOptimizedReplacement()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Returning from old JIT call frame with optimized replacement %p(%p), with success/fail %u/%u", codeBlock, codeBlock->replacement(), codeBlock->replacement()->speculativeSuccessCounter(), codeBlock->replacement()->speculativeFailCounter());
- CallFrame* callerFrame = callFrame->callerFrame();
- if (callerFrame)
- dataLog(", callerFrame = %p, returnPC = %p, caller code block = %p", callerFrame, callFrame->returnPC().value(), callerFrame->codeBlock());
- dataLog("\n");
-#endif
- if (codeBlock->replacement()->shouldReoptimizeNow()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Triggering reoptimization of %p(%p) (in return).\n", codeBlock, codeBlock->replacement());
-#endif
- codeBlock->reoptimize();
- }
-
- codeBlock->optimizeSoon();
- return;
- }
-
- if (!codeBlock->shouldOptimizeNow()) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Delaying optimization for %p (in return) because of insufficient profiling.\n", codeBlock);
-#endif
- return;
- }
-
- ScopeChainNode* scopeChain = callFrame->scopeChain();
-
- JSObject* error = codeBlock->compileOptimized(callFrame, scopeChain);
- if (error)
- dataLog("WARNING: optimized compilation from ret failed.\n");
-
- if (codeBlock->replacement() == codeBlock) {
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from return failed.\n", codeBlock);
-#endif
-
- ASSERT(codeBlock->getJITType() == JITCode::BaselineJIT);
- codeBlock->dontOptimizeAnytimeSoon();
- return;
- }
-
- ASSERT(codeBlock->replacement()->getJITType() == JITCode::DFGJIT);
-
-#if ENABLE(JIT_VERBOSE_OSR)
- dataLog("Optimizing %p from return succeeded after a delay of %u.\n", codeBlock, codeBlock->optimizationDelayCounter());
-#endif
-
- codeBlock->optimizeSoon();
-}
-#endif // ENABLE(DFG_JIT)
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_instanceof)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue value = stackFrame.args[0].jsValue();
- JSValue baseVal = stackFrame.args[1].jsValue();
- JSValue proto = stackFrame.args[2].jsValue();
-
- bool result = CommonSlowPaths::opInstanceOfSlow(callFrame, value, baseVal, proto);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(jsBoolean(result));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_id)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSObject* baseObj = stackFrame.args[0].jsValue().toObject(callFrame);
-
- bool couldDelete = baseObj->methodTable()->deleteProperty(baseObj, callFrame, stackFrame.args[1].identifier());
- JSValue result = jsBoolean(couldDelete);
- if (!couldDelete && callFrame->codeBlock()->isStrictMode())
- stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
-
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_mul)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- if (src1.isNumber() && src2.isNumber())
- return JSValue::encode(jsNumber(src1.asNumber() * src2.asNumber()));
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber(src1.toNumber(callFrame) * src2.toNumber(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_new_func)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- ASSERT(stackFrame.callFrame->codeBlock()->codeType() != FunctionCode || !stackFrame.callFrame->codeBlock()->needsFullScopeChain() || stackFrame.callFrame->uncheckedR(stackFrame.callFrame->codeBlock()->activationRegister()).jsValue());
- return stackFrame.args[0].function()->make(stackFrame.callFrame, stackFrame.callFrame->scopeChain());
-}
-
-inline void* jitCompileFor(CallFrame* callFrame, CodeSpecializationKind kind)
-{
- JSFunction* function = jsCast<JSFunction*>(callFrame->callee());
- ASSERT(!function->isHostFunction());
- FunctionExecutable* executable = function->jsExecutable();
- ScopeChainNode* callDataScopeChain = function->scope();
- JSObject* error = executable->compileFor(callFrame, callDataScopeChain, kind);
- if (!error)
- return function;
- callFrame->globalData().exception = error;
- return 0;
-}
-
-DEFINE_STUB_FUNCTION(void*, op_call_jitCompile)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
-#if !ASSERT_DISABLED
- CallData callData;
- ASSERT(stackFrame.callFrame->callee()->methodTable()->getCallData(stackFrame.callFrame->callee(), callData) == CallTypeJS);
-#endif
-
- CallFrame* callFrame = stackFrame.callFrame;
- void* result = jitCompileFor(callFrame, CodeForCall);
- if (!result)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
-
- return result;
-}
-
-DEFINE_STUB_FUNCTION(void*, op_construct_jitCompile)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
-#if !ASSERT_DISABLED
- ConstructData constructData;
- ASSERT(jsCast<JSFunction*>(stackFrame.callFrame->callee())->methodTable()->getConstructData(stackFrame.callFrame->callee(), constructData) == ConstructTypeJS);
-#endif
-
- CallFrame* callFrame = stackFrame.callFrame;
- void* result = jitCompileFor(callFrame, CodeForConstruct);
- if (!result)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
-
- return result;
-}
-
-DEFINE_STUB_FUNCTION(void*, op_call_arityCheck)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForCall);
- if (!newCallFrame)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
-
- return newCallFrame;
-}
-
-DEFINE_STUB_FUNCTION(void*, op_construct_arityCheck)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- CallFrame* newCallFrame = CommonSlowPaths::arityCheckFor(callFrame, stackFrame.registerFile, CodeForConstruct);
- if (!newCallFrame)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createStackOverflowError(callFrame->callerFrame()));
-
- return newCallFrame;
-}
-
-inline void* lazyLinkFor(CallFrame* callFrame, CodeSpecializationKind kind)
-{
- JSFunction* callee = jsCast<JSFunction*>(callFrame->callee());
- ExecutableBase* executable = callee->executable();
-
- MacroAssemblerCodePtr codePtr;
- CodeBlock* codeBlock = 0;
- CallLinkInfo* callLinkInfo = &callFrame->callerFrame()->codeBlock()->getCallLinkInfo(callFrame->returnPC());
-
- if (executable->isHostFunction())
- codePtr = executable->generatedJITCodeFor(kind).addressForCall();
- else {
- FunctionExecutable* functionExecutable = static_cast<FunctionExecutable*>(executable);
- if (JSObject* error = functionExecutable->compileFor(callFrame, callee->scope(), kind)) {
- callFrame->globalData().exception = error;
- return 0;
- }
- codeBlock = &functionExecutable->generatedBytecodeFor(kind);
- if (callFrame->argumentCountIncludingThis() < static_cast<size_t>(codeBlock->numParameters())
- || callLinkInfo->callType == CallLinkInfo::CallVarargs)
- codePtr = functionExecutable->generatedJITCodeWithArityCheckFor(kind);
- else
- codePtr = functionExecutable->generatedJITCodeFor(kind).addressForCall();
- }
-
- if (!callLinkInfo->seenOnce())
- callLinkInfo->setSeen();
- else
- JIT::linkFor(callee, callFrame->callerFrame()->codeBlock(), codeBlock, codePtr, callLinkInfo, &callFrame->globalData(), kind);
-
- return codePtr.executableAddress();
-}
-
-DEFINE_STUB_FUNCTION(void*, vm_lazyLinkCall)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- void* result = lazyLinkFor(callFrame, CodeForCall);
- if (!result)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
-
- return result;
-}
-
-DEFINE_STUB_FUNCTION(void*, vm_lazyLinkConstruct)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- void* result = lazyLinkFor(callFrame, CodeForConstruct);
- if (!result)
- return throwExceptionFromOpCall<void*>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
-
- return result;
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_push_activation)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSActivation* activation = JSActivation::create(stackFrame.callFrame->globalData(), stackFrame.callFrame, static_cast<FunctionExecutable*>(stackFrame.callFrame->codeBlock()->ownerExecutable()));
- stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(activation));
- return activation;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_NotJSFunction)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue callee = callFrame->calleeAsValue();
-
- CallData callData;
- CallType callType = getCallData(callee, callData);
-
- ASSERT(callType != CallTypeJS);
- if (callType != CallTypeHost) {
- ASSERT(callType == CallTypeNone);
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createNotAFunctionError(callFrame->callerFrame(), callee));
- }
-
- EncodedJSValue returnValue;
- {
- SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
- returnValue = callData.native.function(callFrame);
- }
-
- if (stackFrame.globalData->exception)
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
-
- return returnValue;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_create_arguments)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- Arguments* arguments = Arguments::create(*stackFrame.globalData, stackFrame.callFrame);
- return JSValue::encode(JSValue(arguments));
-}
-
-DEFINE_STUB_FUNCTION(void, op_tear_off_activation)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- ASSERT(callFrame->codeBlock()->needsFullScopeChain());
- JSValue activationValue = stackFrame.args[0].jsValue();
- if (!activationValue) {
- if (JSValue v = stackFrame.args[1].jsValue()) {
- if (!callFrame->codeBlock()->isStrictMode())
- asArguments(v)->tearOff(callFrame);
- }
- return;
- }
- JSActivation* activation = asActivation(stackFrame.args[0].jsValue());
- activation->tearOff(*stackFrame.globalData);
- if (JSValue v = stackFrame.args[1].jsValue())
- asArguments(v)->didTearOffActivation(*stackFrame.globalData, activation);
-}
-
-DEFINE_STUB_FUNCTION(void, op_tear_off_arguments)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- ASSERT(callFrame->codeBlock()->usesArguments() && !callFrame->codeBlock()->needsFullScopeChain());
- asArguments(stackFrame.args[0].jsValue())->tearOff(callFrame);
-}
-
-DEFINE_STUB_FUNCTION(void, op_profile_will_call)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- ASSERT(*stackFrame.enabledProfilerReference);
- (*stackFrame.enabledProfilerReference)->willExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
-}
-
-DEFINE_STUB_FUNCTION(void, op_profile_did_call)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- ASSERT(*stackFrame.enabledProfilerReference);
- (*stackFrame.enabledProfilerReference)->didExecute(stackFrame.callFrame, stackFrame.args[0].jsValue());
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_new_array)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return constructArray(stackFrame.callFrame, reinterpret_cast<JSValue*>(&stackFrame.callFrame->registers()[stackFrame.args[0].int32()]), stackFrame.args[1].int32());
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_new_array_buffer)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return constructArray(stackFrame.callFrame, stackFrame.callFrame->codeBlock()->constantBuffer(stackFrame.args[0].int32()), stackFrame.args[1].int32());
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue result = CommonSlowPaths::opResolve(callFrame, stackFrame.args[0].identifier());
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_construct_NotJSConstruct)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue callee = callFrame->calleeAsValue();
-
- ConstructData constructData;
- ConstructType constructType = getConstructData(callee, constructData);
-
- ASSERT(constructType != ConstructTypeJS);
- if (constructType != ConstructTypeHost) {
- ASSERT(constructType == ConstructTypeNone);
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS, createNotAConstructorError(callFrame->callerFrame(), callee));
- }
-
- EncodedJSValue returnValue;
- {
- SamplingTool::HostCallRecord callRecord(CTI_SAMPLER);
- returnValue = constructData.native.function(callFrame);
- }
-
- if (stackFrame.globalData->exception)
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
-
- return returnValue;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue baseValue = stackFrame.args[0].jsValue();
- JSValue subscript = stackFrame.args[1].jsValue();
-
- if (LIKELY(baseValue.isCell() && subscript.isString())) {
- if (JSValue result = baseValue.asCell()->fastGetOwnProperty(callFrame, asString(subscript)->value(callFrame))) {
- CHECK_FOR_EXCEPTION();
- return JSValue::encode(result);
- }
- }
-
- if (subscript.isUInt32()) {
- uint32_t i = subscript.asUInt32();
- if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i)) {
- ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val_string));
- JSValue result = asString(baseValue)->getIndex(callFrame, i);
- CHECK_FOR_EXCEPTION();
- return JSValue::encode(result);
- }
- JSValue result = baseValue.get(callFrame, i);
- CHECK_FOR_EXCEPTION();
- return JSValue::encode(result);
- }
-
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- JSValue result = baseValue.get(callFrame, property);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_get_by_val_string)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue baseValue = stackFrame.args[0].jsValue();
- JSValue subscript = stackFrame.args[1].jsValue();
-
- JSValue result;
-
- if (LIKELY(subscript.isUInt32())) {
- uint32_t i = subscript.asUInt32();
- if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
- result = asString(baseValue)->getIndex(callFrame, i);
- else {
- result = baseValue.get(callFrame, i);
- if (!isJSString(baseValue))
- ctiPatchCallByReturnAddress(callFrame->codeBlock(), STUB_RETURN_ADDRESS, FunctionPtr(cti_op_get_by_val));
- }
- } else {
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- result = baseValue.get(callFrame, property);
- }
-
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_sub)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- if (src1.isNumber() && src2.isNumber())
- return JSValue::encode(jsNumber(src1.asNumber() - src2.asNumber()));
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber(src1.toNumber(callFrame) - src2.toNumber(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(void, op_put_by_val)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSGlobalData* globalData = stackFrame.globalData;
-
- JSValue baseValue = stackFrame.args[0].jsValue();
- JSValue subscript = stackFrame.args[1].jsValue();
- JSValue value = stackFrame.args[2].jsValue();
-
- if (LIKELY(subscript.isUInt32())) {
- uint32_t i = subscript.asUInt32();
- if (isJSArray(baseValue)) {
- JSArray* jsArray = asArray(baseValue);
- if (jsArray->canSetIndex(i))
- jsArray->setIndex(*globalData, i, value);
- else
- JSArray::putByIndex(jsArray, callFrame, i, value, callFrame->codeBlock()->isStrictMode());
- } else
- baseValue.putByIndex(callFrame, i, value, callFrame->codeBlock()->isStrictMode());
- } else {
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- if (!stackFrame.globalData->exception) { // Don't put to an object if toString threw an exception.
- PutPropertySlot slot(callFrame->codeBlock()->isStrictMode());
- baseValue.put(callFrame, property, value, slot);
- }
- }
-
- CHECK_FOR_EXCEPTION_AT_END();
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_less)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsBoolean(jsLess<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_lesseq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsBoolean(jsLessEq<true>(callFrame, stackFrame.args[0].jsValue(), stackFrame.args[1].jsValue()));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_greater)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsBoolean(jsLess<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_greatereq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsBoolean(jsLessEq<false>(callFrame, stackFrame.args[1].jsValue(), stackFrame.args[0].jsValue()));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(void*, op_load_varargs)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- RegisterFile* registerFile = stackFrame.registerFile;
- JSValue thisValue = stackFrame.args[0].jsValue();
- JSValue arguments = stackFrame.args[1].jsValue();
- int firstFreeRegister = stackFrame.args[2].int32();
-
- CallFrame* newCallFrame = loadVarargs(callFrame, registerFile, thisValue, arguments, firstFreeRegister);
- if (!newCallFrame)
- VM_THROW_EXCEPTION();
- return newCallFrame;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_negate)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src = stackFrame.args[0].jsValue();
-
- if (src.isNumber())
- return JSValue::encode(jsNumber(-src.asNumber()));
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber(-src.toNumber(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), false));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_base_strict_put)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
- JSValue base = JSC::resolveBase(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.callFrame->scopeChain(), true);
- if (!base) {
- stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[0].identifier().ustring());
- VM_THROW_EXCEPTION();
- }
- return JSValue::encode(base);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_ensure_property_exists)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
- JSValue base = stackFrame.callFrame->r(stackFrame.args[0].int32()).jsValue();
- JSObject* object = asObject(base);
- PropertySlot slot(object);
- ASSERT(stackFrame.callFrame->codeBlock()->isStrictMode());
- if (!object->getPropertySlot(stackFrame.callFrame, stackFrame.args[1].identifier(), slot)) {
- stackFrame.globalData->exception = createErrorForInvalidGlobalAssignment(stackFrame.callFrame, stackFrame.args[1].identifier().ustring());
- VM_THROW_EXCEPTION();
- }
-
- return JSValue::encode(base);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_skip)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue result = CommonSlowPaths::opResolveSkip(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].int32());
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_global)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- CodeBlock* codeBlock = callFrame->codeBlock();
- JSGlobalObject* globalObject = codeBlock->globalObject();
- Identifier& ident = stackFrame.args[0].identifier();
- unsigned globalResolveInfoIndex = stackFrame.args[1].int32();
- ASSERT(globalObject->isGlobalObject());
-
- PropertySlot slot(globalObject);
- if (globalObject->getPropertySlot(callFrame, ident, slot)) {
- JSValue result = slot.getValue(callFrame, ident);
- if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
- GlobalResolveInfo& globalResolveInfo = codeBlock->globalResolveInfo(globalResolveInfoIndex);
- globalResolveInfo.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
- globalResolveInfo.offset = slot.cachedOffset();
- return JSValue::encode(result);
- }
-
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
- }
-
- stackFrame.globalData->exception = createUndefinedVariableError(callFrame, ident);
- VM_THROW_EXCEPTION();
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_div)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- if (src1.isNumber() && src2.isNumber())
- return JSValue::encode(jsNumber(src1.asNumber() / src2.asNumber()));
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber(src1.toNumber(callFrame) / src2.toNumber(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_pre_dec)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber(v.toNumber(callFrame) - 1);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(int, op_jless)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = jsLess<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(int, op_jlesseq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = jsLessEq<true>(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(int, op_jgreater)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = jsLess<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(int, op_jgreatereq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = jsLessEq<false>(callFrame, src2, src1);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_not)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue result = jsBoolean(!src.toBoolean(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(int, op_jtrue)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = src1.toBoolean(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_inc)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- double number = v.toNumber(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
-
- callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number + 1);
- return JSValue::encode(jsNumber(number));
-}
-
-DEFINE_STUB_FUNCTION(int, op_eq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
-#if USE(JSVALUE32_64)
- start:
- if (src2.isUndefined()) {
- return src1.isNull() ||
- (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
- || src1.isUndefined();
- }
-
- if (src2.isNull()) {
- return src1.isUndefined() ||
- (src1.isCell() && src1.asCell()->structure()->typeInfo().masqueradesAsUndefined())
- || src1.isNull();
- }
-
- if (src1.isInt32()) {
- if (src2.isDouble())
- return src1.asInt32() == src2.asDouble();
- double d = src2.toNumber(stackFrame.callFrame);
- CHECK_FOR_EXCEPTION();
- return src1.asInt32() == d;
- }
-
- if (src1.isDouble()) {
- if (src2.isInt32())
- return src1.asDouble() == src2.asInt32();
- double d = src2.toNumber(stackFrame.callFrame);
- CHECK_FOR_EXCEPTION();
- return src1.asDouble() == d;
- }
-
- if (src1.isTrue()) {
- if (src2.isFalse())
- return false;
- double d = src2.toNumber(stackFrame.callFrame);
- CHECK_FOR_EXCEPTION();
- return d == 1.0;
- }
-
- if (src1.isFalse()) {
- if (src2.isTrue())
- return false;
- double d = src2.toNumber(stackFrame.callFrame);
- CHECK_FOR_EXCEPTION();
- return d == 0.0;
- }
-
- if (src1.isUndefined())
- return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
-
- if (src1.isNull())
- return src2.isCell() && src2.asCell()->structure()->typeInfo().masqueradesAsUndefined();
-
- JSCell* cell1 = src1.asCell();
-
- if (cell1->isString()) {
- if (src2.isInt32())
- return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asInt32();
-
- if (src2.isDouble())
- return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == src2.asDouble();
-
- if (src2.isTrue())
- return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 1.0;
-
- if (src2.isFalse())
- return jsToNumber(jsCast<JSString*>(cell1)->value(stackFrame.callFrame)) == 0.0;
-
- JSCell* cell2 = src2.asCell();
- if (cell2->isString())
- return jsCast<JSString*>(cell1)->value(stackFrame.callFrame) == jsCast<JSString*>(cell2)->value(stackFrame.callFrame);
-
- src2 = asObject(cell2)->toPrimitive(stackFrame.callFrame);
- CHECK_FOR_EXCEPTION();
- goto start;
- }
-
- if (src2.isObject())
- return asObject(cell1) == asObject(src2);
- src1 = asObject(cell1)->toPrimitive(stackFrame.callFrame);
- CHECK_FOR_EXCEPTION();
- goto start;
-
-#else // USE(JSVALUE32_64)
- CallFrame* callFrame = stackFrame.callFrame;
-
- bool result = JSValue::equalSlowCaseInline(callFrame, src1, src2);
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-#endif // USE(JSVALUE32_64)
-}
-
-DEFINE_STUB_FUNCTION(int, op_eq_strings)
-{
-#if USE(JSVALUE32_64)
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSString* string1 = stackFrame.args[0].jsString();
- JSString* string2 = stackFrame.args[1].jsString();
-
- ASSERT(string1->isString());
- ASSERT(string2->isString());
- return string1->value(stackFrame.callFrame) == string2->value(stackFrame.callFrame);
-#else
- UNUSED_PARAM(args);
- ASSERT_NOT_REACHED();
- return 0;
-#endif
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_lshift)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue val = stackFrame.args[0].jsValue();
- JSValue shift = stackFrame.args[1].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber((val.toInt32(callFrame)) << (shift.toUInt32(callFrame) & 0x1f));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitand)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- ASSERT(!src1.isInt32() || !src2.isInt32());
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber(src1.toInt32(callFrame) & src2.toInt32(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_rshift)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue val = stackFrame.args[0].jsValue();
- JSValue shift = stackFrame.args[1].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber((val.toInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
-
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_base)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = CommonSlowPaths::opResolveWithBase(callFrame, stackFrame.args[0].identifier(), callFrame->registers()[stackFrame.args[1].int32()]);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_resolve_with_this)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = CommonSlowPaths::opResolveWithThis(callFrame, stackFrame.args[0].identifier(), callFrame->registers()[stackFrame.args[1].int32()]);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_new_func_exp)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
- CallFrame* callFrame = stackFrame.callFrame;
-
- FunctionExecutable* function = stackFrame.args[0].function();
- JSFunction* func = function->make(callFrame, callFrame->scopeChain());
- ASSERT(callFrame->codeBlock()->codeType() != FunctionCode || !callFrame->codeBlock()->needsFullScopeChain() || callFrame->uncheckedR(callFrame->codeBlock()->activationRegister()).jsValue());
-
- /*
- The Identifier in a FunctionExpression can be referenced from inside
- the FunctionExpression's FunctionBody to allow the function to call
- itself recursively. However, unlike in a FunctionDeclaration, the
- Identifier in a FunctionExpression cannot be referenced from and
- does not affect the scope enclosing the FunctionExpression.
- */
- if (!function->name().isNull()) {
- JSStaticScopeObject* functionScopeObject = JSStaticScopeObject::create(callFrame, function->name(), func, ReadOnly | DontDelete);
- func->setScope(callFrame->globalData(), func->scope()->push(functionScopeObject));
- }
-
- return func;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_mod)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue dividendValue = stackFrame.args[0].jsValue();
- JSValue divisorValue = stackFrame.args[1].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
- double d = dividendValue.toNumber(callFrame);
- JSValue result = jsNumber(fmod(d, divisorValue.toNumber(callFrame)));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_post_dec)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue v = stackFrame.args[0].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- double number = v.toNumber(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
-
- callFrame->registers()[stackFrame.args[1].int32()] = jsNumber(number - 1);
- return JSValue::encode(jsNumber(number));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_urshift)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue val = stackFrame.args[0].jsValue();
- JSValue shift = stackFrame.args[1].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue result = jsNumber((val.toUInt32(callFrame)) >> (shift.toUInt32(callFrame) & 0x1f));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitxor)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue result = jsNumber(src1.toInt32(callFrame) ^ src2.toInt32(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_new_regexp)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- RegExp* regExp = stackFrame.args[0].regExp();
- if (!regExp->isValid()) {
- stackFrame.globalData->exception = createSyntaxError(callFrame, "Invalid flags supplied to RegExp constructor.");
- VM_THROW_EXCEPTION();
- }
-
- return RegExpObject::create(*stackFrame.globalData, stackFrame.callFrame->lexicalGlobalObject(), stackFrame.callFrame->lexicalGlobalObject()->regExpStructure(), regExp);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_bitor)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue result = jsNumber(src1.toInt32(callFrame) | src2.toInt32(callFrame));
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_call_eval)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- CallFrame* callerFrame = callFrame->callerFrame();
- ASSERT(callFrame->callerFrame()->codeBlock()->codeType() != FunctionCode
- || !callFrame->callerFrame()->codeBlock()->needsFullScopeChain()
- || callFrame->callerFrame()->uncheckedR(callFrame->callerFrame()->codeBlock()->activationRegister()).jsValue());
-
- callFrame->setScopeChain(callerFrame->scopeChain());
- callFrame->setReturnPC(static_cast<Instruction*>((STUB_RETURN_ADDRESS).value()));
- callFrame->setCodeBlock(0);
-
- if (!isHostFunction(callFrame->calleeAsValue(), globalFuncEval))
- return JSValue::encode(JSValue());
-
- JSValue result = eval(callFrame);
- if (stackFrame.globalData->exception)
- return throwExceptionFromOpCall<EncodedJSValue>(stackFrame, callFrame, STUB_RETURN_ADDRESS);
-
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(void*, op_throw)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
- ExceptionHandler handler = jitThrow(stackFrame.globalData, stackFrame.callFrame, stackFrame.args[0].jsValue(), STUB_RETURN_ADDRESS);
- STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
- return handler.callFrame;
-}
-
-DEFINE_STUB_FUNCTION(JSPropertyNameIterator*, op_get_pnames)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSObject* o = stackFrame.args[0].jsObject();
- Structure* structure = o->structure();
- JSPropertyNameIterator* jsPropertyNameIterator = structure->enumerationCache();
- if (!jsPropertyNameIterator || jsPropertyNameIterator->cachedPrototypeChain() != structure->prototypeChain(callFrame))
- jsPropertyNameIterator = JSPropertyNameIterator::create(callFrame, o);
- return jsPropertyNameIterator;
-}
-
-DEFINE_STUB_FUNCTION(int, has_property)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSObject* base = stackFrame.args[0].jsObject();
- JSString* property = stackFrame.args[1].jsString();
- int result = base->hasProperty(stackFrame.callFrame, Identifier(stackFrame.callFrame, property->value(stackFrame.callFrame)));
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_push_scope)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSObject* o = stackFrame.args[0].jsValue().toObject(stackFrame.callFrame);
- CHECK_FOR_EXCEPTION();
- stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->push(o));
- return o;
-}
-
-DEFINE_STUB_FUNCTION(void, op_pop_scope)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- stackFrame.callFrame->setScopeChain(stackFrame.callFrame->scopeChain()->pop());
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_typeof)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(jsTypeStringForValue(stackFrame.callFrame, stackFrame.args[0].jsValue()));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_object)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(jsBoolean(jsIsObjectType(stackFrame.args[0].jsValue())));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_is_function)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(jsBoolean(jsIsFunctionType(stackFrame.args[0].jsValue())));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_stricteq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- bool result = JSValue::strictEqual(stackFrame.callFrame, src1, src2);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(jsBoolean(result));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_primitive)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- return JSValue::encode(stackFrame.args[0].jsValue().toPrimitive(stackFrame.callFrame));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_strcat)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue result = jsString(stackFrame.callFrame, &stackFrame.callFrame->registers()[stackFrame.args[0].int32()], stackFrame.args[1].int32());
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(result);
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_nstricteq)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src1 = stackFrame.args[0].jsValue();
- JSValue src2 = stackFrame.args[1].jsValue();
-
- bool result = !JSValue::strictEqual(stackFrame.callFrame, src1, src2);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(jsBoolean(result));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_to_jsnumber)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue src = stackFrame.args[0].jsValue();
- CallFrame* callFrame = stackFrame.callFrame;
-
- double number = src.toNumber(callFrame);
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(jsNumber(number));
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_in)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- JSValue baseVal = stackFrame.args[1].jsValue();
-
- if (!baseVal.isObject()) {
- stackFrame.globalData->exception = createInvalidParamError(stackFrame.callFrame, "in", baseVal);
- VM_THROW_EXCEPTION();
- }
-
- JSValue propName = stackFrame.args[0].jsValue();
- JSObject* baseObj = asObject(baseVal);
-
- uint32_t i;
- if (propName.getUInt32(i))
- return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, i)));
-
- Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
- CHECK_FOR_EXCEPTION();
- return JSValue::encode(jsBoolean(baseObj->hasProperty(callFrame, property)));
-}
-
-DEFINE_STUB_FUNCTION(JSObject*, op_push_new_scope)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSObject* scope = JSStaticScopeObject::create(stackFrame.callFrame, stackFrame.args[0].identifier(), stackFrame.args[1].jsValue(), DontDelete);
-
- CallFrame* callFrame = stackFrame.callFrame;
- callFrame->setScopeChain(callFrame->scopeChain()->push(scope));
- return scope;
-}
-
-DEFINE_STUB_FUNCTION(void, op_jmp_scopes)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- unsigned count = stackFrame.args[0].int32();
- CallFrame* callFrame = stackFrame.callFrame;
-
- ScopeChainNode* tmp = callFrame->scopeChain();
- while (count--)
- tmp = tmp->pop();
- callFrame->setScopeChain(tmp);
-}
-
-DEFINE_STUB_FUNCTION(void, op_put_by_index)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- unsigned property = stackFrame.args[1].int32();
-
- JSValue arrayValue = stackFrame.args[0].jsValue();
- ASSERT(isJSArray(arrayValue));
- asArray(arrayValue)->putDirectIndex(callFrame, property, stackFrame.args[2].jsValue(), false);
-}
-
-DEFINE_STUB_FUNCTION(void*, op_switch_imm)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue scrutinee = stackFrame.args[0].jsValue();
- unsigned tableIndex = stackFrame.args[1].int32();
- CallFrame* callFrame = stackFrame.callFrame;
- CodeBlock* codeBlock = callFrame->codeBlock();
-
- if (scrutinee.isInt32())
- return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(scrutinee.asInt32()).executableAddress();
- if (scrutinee.isDouble() && scrutinee.asDouble() == static_cast<int32_t>(scrutinee.asDouble()))
- return codeBlock->immediateSwitchJumpTable(tableIndex).ctiForValue(static_cast<int32_t>(scrutinee.asDouble())).executableAddress();
- return codeBlock->immediateSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
-}
-
-DEFINE_STUB_FUNCTION(void*, op_switch_char)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue scrutinee = stackFrame.args[0].jsValue();
- unsigned tableIndex = stackFrame.args[1].int32();
- CallFrame* callFrame = stackFrame.callFrame;
- CodeBlock* codeBlock = callFrame->codeBlock();
-
- void* result = codeBlock->characterSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
-
- if (scrutinee.isString()) {
- StringImpl* value = asString(scrutinee)->value(callFrame).impl();
- if (value->length() == 1)
- result = codeBlock->characterSwitchJumpTable(tableIndex).ctiForValue((*value)[0]).executableAddress();
- }
-
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(void*, op_switch_string)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- JSValue scrutinee = stackFrame.args[0].jsValue();
- unsigned tableIndex = stackFrame.args[1].int32();
- CallFrame* callFrame = stackFrame.callFrame;
- CodeBlock* codeBlock = callFrame->codeBlock();
-
- void* result = codeBlock->stringSwitchJumpTable(tableIndex).ctiDefault.executableAddress();
-
- if (scrutinee.isString()) {
- StringImpl* value = asString(scrutinee)->value(callFrame).impl();
- result = codeBlock->stringSwitchJumpTable(tableIndex).ctiForValue(value).executableAddress();
- }
-
- CHECK_FOR_EXCEPTION_AT_END();
- return result;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, op_del_by_val)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- JSValue baseValue = stackFrame.args[0].jsValue();
- JSObject* baseObj = baseValue.toObject(callFrame); // may throw
-
- JSValue subscript = stackFrame.args[1].jsValue();
- bool result;
- uint32_t i;
- if (subscript.getUInt32(i))
- result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
- else {
- CHECK_FOR_EXCEPTION();
- Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
- CHECK_FOR_EXCEPTION();
- result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property);
- }
-
- if (!result && callFrame->codeBlock()->isStrictMode())
- stackFrame.globalData->exception = createTypeError(stackFrame.callFrame, "Unable to delete property.");
-
- CHECK_FOR_EXCEPTION_AT_END();
- return JSValue::encode(jsBoolean(result));
-}
-
-DEFINE_STUB_FUNCTION(void, op_put_getter_setter)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- ASSERT(stackFrame.args[0].jsValue().isObject());
- JSObject* baseObj = asObject(stackFrame.args[0].jsValue());
-
- GetterSetter* accessor = GetterSetter::create(callFrame);
-
- JSValue getter = stackFrame.args[2].jsValue();
- JSValue setter = stackFrame.args[3].jsValue();
- ASSERT(getter.isObject() || getter.isUndefined());
- ASSERT(setter.isObject() || setter.isUndefined());
- ASSERT(getter.isObject() || setter.isObject());
-
- if (!getter.isUndefined())
- accessor->setGetter(callFrame->globalData(), asObject(getter));
- if (!setter.isUndefined())
- accessor->setSetter(callFrame->globalData(), asObject(setter));
- baseObj->putDirectAccessor(callFrame->globalData(), stackFrame.args[1].identifier(), accessor, Accessor);
-}
-
-DEFINE_STUB_FUNCTION(void, op_throw_reference_error)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- UString message = stackFrame.args[0].jsValue().toString(callFrame)->value(callFrame);
- stackFrame.globalData->exception = createReferenceError(callFrame, message);
- VM_THROW_EXCEPTION_AT_END();
-}
-
-DEFINE_STUB_FUNCTION(void, op_debug)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
-
- int debugHookID = stackFrame.args[0].int32();
- int firstLine = stackFrame.args[1].int32();
- int lastLine = stackFrame.args[2].int32();
-
- stackFrame.globalData->interpreter->debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
-}
-
-DEFINE_STUB_FUNCTION(void*, vm_throw)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
- JSGlobalData* globalData = stackFrame.globalData;
- ExceptionHandler handler = jitThrow(globalData, stackFrame.callFrame, globalData->exception, globalData->exceptionLocation);
- STUB_SET_RETURN_ADDRESS(handler.catchRoutine);
- return handler.callFrame;
-}
-
-DEFINE_STUB_FUNCTION(EncodedJSValue, to_object)
-{
- STUB_INIT_STACK_FRAME(stackFrame);
-
- CallFrame* callFrame = stackFrame.callFrame;
- return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame));
-}
-
-MacroAssemblerCodeRef JITThunks::ctiStub(JSGlobalData* globalData, ThunkGenerator generator)
-{
- CTIStubMap::AddResult entry = m_ctiStubMap.add(generator, MacroAssemblerCodeRef());
- if (entry.isNewEntry)
- entry.iterator->second = generator(globalData);
- return entry.iterator->second;
-}
-
-NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, NativeFunction constructor)
-{
- HostFunctionStubMap::AddResult result = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
- if (!result.iterator->second)
- result.iterator->second = PassWeak<NativeExecutable>(NativeExecutable::create(*globalData, JIT::compileCTINativeCall(globalData, function), function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), constructor, NoIntrinsic));
- return result.iterator->second.get();
-}
-
-NativeExecutable* JITThunks::hostFunctionStub(JSGlobalData* globalData, NativeFunction function, ThunkGenerator generator, Intrinsic intrinsic)
-{
- HostFunctionStubMap::AddResult entry = m_hostFunctionStubMap->add(function, PassWeak<NativeExecutable>());
- if (!entry.iterator->second) {
- MacroAssemblerCodeRef code;
- if (generator) {
- if (globalData->canUseJIT())
- code = generator(globalData);
- else
- code = MacroAssemblerCodeRef();
- } else
- code = JIT::compileCTINativeCall(globalData, function);
- entry.iterator->second = PassWeak<NativeExecutable>(NativeExecutable::create(*globalData, code, function, MacroAssemblerCodeRef::createSelfManagedCodeRef(ctiNativeConstruct()), callHostFunctionAsConstructor, intrinsic));
- }
- return entry.iterator->second.get();
-}
-
-void JITThunks::clearHostFunctionStubs()
-{
- m_hostFunctionStubMap.clear();
-}
-
-} // namespace JSC