bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, SQLError* error)
{
    ASSERT(m_callback);
    ASSERT(m_frame);
        
    if (!m_frame->script()->isEnabled())
        return true;
        
    JSGlobalObject* globalObject = m_frame->script()->globalObject();
    ExecState* exec = globalObject->globalExec();
        
    KJS::JSLock lock;
        
    JSValue* handleEventFunction = m_callback->get(exec, Identifier(exec, "handleEvent"));
    CallData handleEventCallData;
    CallType handleEventCallType = handleEventFunction->getCallData(handleEventCallData);
    CallData callbackCallData;
    CallType callbackCallType = CallTypeNone;

    if (handleEventCallType == CallTypeNone) {
        callbackCallType = m_callback->getCallData(callbackCallData);
        if (callbackCallType == CallTypeNone) {
            // FIXME: Should an exception be thrown here?
            return true;
        }
    }
        
    RefPtr<JSCustomSQLStatementErrorCallback> protect(this);
        
    ArgList args;
    args.append(toJS(exec, transaction));
    args.append(toJS(exec, error));
        
    JSValue* result;
    globalObject->startTimeoutCheck();
    if (handleEventCallType != CallTypeNone)
        result = call(exec, handleEventFunction, handleEventCallType, handleEventCallData, m_callback, args);
    else
        result = call(exec, m_callback, callbackCallType, callbackCallData, m_callback, args);
    globalObject->stopTimeoutCheck();
        
    if (exec->hadException()) {
        JSObject* exception = exec->exception()->toObject(exec);
        String message = exception->get(exec, exec->propertyNames().message)->toString(exec);
        int lineNumber = exception->get(exec, Identifier(exec, "line"))->toInt32(exec);
        String sourceURL = exception->get(exec, Identifier(exec, "sourceURL"))->toString(exec);
        m_frame->domWindow()->console()->addMessage(JSMessageSource, ErrorMessageLevel, message, lineNumber, sourceURL);
        exec->clearException();
            
        // The spec says:
        // "If the error callback returns false, then move on to the next statement..."
        // "Otherwise, the error callback did not return false, or there was no error callback"
        // Therefore an exception and returning true are the same thing - so, return true on an exception
        return true;
    }
        
    Document::updateDocumentsRendering();

    return result->toBoolean(exec);
}
Esempio n. 2
0
PassRefPtr<FunctionCodeBlock> FunctionExecutable::produceCodeBlockFor(JSScope* scope, CodeSpecializationKind specializationKind, JSObject*& exception)
{
    RefPtr<FunctionCodeBlock> alternative = codeBlockFor(specializationKind);
    
    if (!!alternative) {
        RefPtr<FunctionCodeBlock> result = adoptRef(new FunctionCodeBlock(CodeBlock::CopyParsedBlock, *codeBlockFor(specializationKind)));
        result->setAlternative(alternative);
        return result.release();
    }

    VM* vm = scope->vm();
    JSGlobalObject* globalObject = scope->globalObject();
    ParserError error;
    DebuggerMode debuggerMode = globalObject->hasDebugger() ? DebuggerOn : DebuggerOff;
    ProfilerMode profilerMode = globalObject->hasProfiler() ? ProfilerOn : ProfilerOff;
    UnlinkedFunctionCodeBlock* unlinkedCodeBlock = m_unlinkedExecutable->codeBlockFor(*vm, m_source, specializationKind, debuggerMode, profilerMode, error);
    recordParse(m_unlinkedExecutable->features(), m_unlinkedExecutable->hasCapturedVariables(), lineNo(), lastLine(), startColumn());

    if (!unlinkedCodeBlock) {
        exception = error.toErrorObject(globalObject, m_source);
        return 0;
    }

    SourceProvider* provider = source().provider();
    unsigned sourceOffset = source().startOffset();
    unsigned startColumn = source().startColumn();

    return adoptRef(new FunctionCodeBlock(this, unlinkedCodeBlock, scope, provider, sourceOffset, startColumn));
}
Esempio n. 3
0
JSBool JSJSGlobalObject::fromjs_isTimerValid(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
  // get instance
  JSGlobalObject *object = static_cast<JSGlobalObject *>(reinterpret_cast<JSScriptable *>(JS_GetPrivate(cx, obj)));
  if (!object) {
    JSScriptable::js_throwNullCallException(JSJSGlobalObject::classDescriptor.name, JSJSGlobalObject::functionTable[4].name);
    return JS_FALSE;
  }
  // record context
  object->js_setCurrentContext(cx);
  // JSTimer *timer
  JSObject *p0;
  if (!JS_ValueToObject(cx, argv[0], &p0))
    return JS_FALSE;
  argv[0] = OBJECT_TO_JSVAL(p0);
  JSTimer *p0o = NULL;
  if (p0) {
    JSScriptable *pobj = reinterpret_cast<JSScriptable*>(JS_GetPrivate(cx, p0));
    if (!pobj) {
      object->js_throwNullParamException(0, JSJSGlobalObject::functionTable[4].name, JSJSGlobalObject::classDescriptor.name);
      return JS_FALSE;
    }
    p0o = static_cast<JSTimer *>(pobj->js_getInterface(JS_JSTimer_GUID));
    if (!p0o) {
      object->js_throwParamTypeException(0, JSJSTimer::classDescriptor.name, JSJSGlobalObject::functionTable[4].name, JSJSGlobalObject::classDescriptor.name);
      return JS_FALSE;
    }
  }
  // call method
  ASSERT(object != NULL);
  bool rv = object->isTimerValid(p0o);
  // handle return value
  *rval = BOOLEAN_TO_JSVAL(rv);
  // success
  return JS_TRUE;
}
Esempio n. 4
0
bool FunctionExecutable::compileForConstruct(ExecState*, ScopeChainNode* scopeChainNode)
{
    JSGlobalData* globalData = scopeChainNode->globalData;
    RefPtr<FunctionBodyNode> body = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
    if (!body)
        return false;
    if (m_forceUsesArguments)
        body->setUsesArguments();
    body->finishParsing(m_parameters, m_name);
    recordParse(body->features(), body->lineNo(), body->lastLine());

    ScopeChain scopeChain(scopeChainNode);
    JSGlobalObject* globalObject = scopeChain.globalObject();

    ASSERT(!m_codeBlockForConstruct);
    m_codeBlockForConstruct = new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset(), true);
    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(body.get(), globalObject->debugger(), scopeChain, m_codeBlockForConstruct->symbolTable(), m_codeBlockForConstruct));
    generator->generate();
    m_numParametersForConstruct = m_codeBlockForConstruct->m_numParameters;
    ASSERT(m_numParametersForConstruct);
    m_numVariables = m_codeBlockForConstruct->m_numVars;
    m_symbolTable = m_codeBlockForConstruct->sharedSymbolTable();

    body->destroyData();
    return true;
}
Esempio n. 5
0
std::error_code parseRuleList(const String& rules, Vector<ContentExtensionRule>& ruleList)
{
#if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING
    double loadExtensionStartTime = monotonicallyIncreasingTime();
#endif
    RefPtr<VM> vm = VM::create();

    JSLockHolder locker(vm.get());
    JSGlobalObject* globalObject = JSGlobalObject::create(*vm, JSGlobalObject::createStructure(*vm, jsNull()));

    ExecState* exec = globalObject->globalExec();
    auto error = loadEncodedRules(*exec, rules, ruleList);

    vm = nullptr;

    if (error)
        return error;

    if (ruleList.isEmpty())
        return ContentExtensionError::JSONContainsNoRules;

#if CONTENT_EXTENSIONS_PERFORMANCE_REPORTING
    double loadExtensionEndTime = monotonicallyIncreasingTime();
    dataLogF("Time spent loading extension %f\n", (loadExtensionEndTime - loadExtensionStartTime));
#endif

    return { };
}
Esempio n. 6
0
String Database::toJSON() const
{
    JSGlobalObject* globalObject = JSGlobalObject::create(
        m_vm, JSGlobalObject::createStructure(m_vm, jsNull()));
    
    return JSONStringify(globalObject->globalExec(), toJS(globalObject->globalExec()), 0);
}
Esempio n. 7
0
JSObject* ProgramExecutable::initializeGlobalProperties(VM& vm, CallFrame* callFrame, JSScope* scope)
{
    RELEASE_ASSERT(scope);
    JSGlobalObject* globalObject = scope->globalObject();
    RELEASE_ASSERT(globalObject);
    ASSERT(&globalObject->vm() == &vm);

    JSObject* exception = 0;
    UnlinkedProgramCodeBlock* unlinkedCodeBlock = globalObject->createProgramCodeBlock(callFrame, this, &exception);
    if (exception)
        return exception;

    m_unlinkedProgramCodeBlock.set(vm, this, unlinkedCodeBlock);

    BatchedTransitionOptimizer optimizer(vm, globalObject);

    for (size_t i = 0, numberOfFunctions = unlinkedCodeBlock->numberOfFunctionDecls(); i < numberOfFunctions; ++i) {
        UnlinkedFunctionExecutable* unlinkedFunctionExecutable = unlinkedCodeBlock->functionDecl(i);
        ASSERT(!unlinkedFunctionExecutable->name().isEmpty());
        globalObject->addFunction(callFrame, unlinkedFunctionExecutable->name());
        if (vm.typeProfiler() || vm.controlFlowProfiler()) {
            vm.functionHasExecutedCache()->insertUnexecutedRange(sourceID(), 
                unlinkedFunctionExecutable->typeProfilingStartOffset(), 
                unlinkedFunctionExecutable->typeProfilingEndOffset());
        }
    }

    const VariableEnvironment& variableDeclarations = unlinkedCodeBlock->variableDeclarations();
    for (auto& entry : variableDeclarations) {
        ASSERT(entry.value.isVar());
        globalObject->addVar(callFrame, Identifier::fromUid(&vm, entry.key.get()));
    }
    return 0;
}
EncodedJSValue jsTestNondeterministicNondeterministicSetterExceptionAttr(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    UNUSED_PARAM(state);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSTestNondeterministic*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, "TestNondeterministic", "nondeterministicSetterExceptionAttr");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = state->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("TestNondeterministic.nondeterministicSetterExceptionAttr", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->wrapped().nondeterministicSetterExceptionAttr();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(state, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(state, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.nondeterministicSetterExceptionAttr());
    return JSValue::encode(result);
}
Esempio n. 9
0
JSObject* ProgramExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode)
{
    ASSERT(!m_programCodeBlock);

    JSObject* exception = 0;
    JSGlobalData* globalData = &exec->globalData();
    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    RefPtr<ProgramNode> programNode = globalData->parser->parse<ProgramNode>(lexicalGlobalObject, lexicalGlobalObject->debugger(), exec, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, &exception);
    if (!programNode) {
        ASSERT(exception);
        return exception;
    }
    recordParse(programNode->features(), programNode->hasCapturedVariables(), programNode->lineNo(), programNode->lastLine());

    ScopeChain scopeChain(scopeChainNode);
    JSGlobalObject* globalObject = scopeChain.globalObject();
    
    m_programCodeBlock = adoptPtr(new ProgramCodeBlock(this, GlobalCode, globalObject, source().provider()));
    OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(programNode.get(), scopeChain, &globalObject->symbolTable(), m_programCodeBlock.get())));
    generator->generate();

    programNode->destroyData();

#if ENABLE(JIT)
    if (exec->globalData().canUseJIT()) {
        m_jitCodeForCall = JIT::compile(scopeChainNode->globalData, m_programCodeBlock.get());
#if !ENABLE(OPCODE_SAMPLING)
        if (!BytecodeGenerator::dumpsGeneratedCode())
            m_programCodeBlock->discardBytecode();
#endif
    }
#endif

   return 0;
}
Esempio n. 10
0
JSValueRef JSEvaluateScriptInternal(const JSLockHolder&, ExecState* exec, JSContextRef ctx, JSObjectRef thisObject, const SourceCode& source, JSValueRef* exception)
{
    UNUSED_PARAM(ctx);

    JSObject* jsThisObject = toJS(thisObject);

    // evaluate sets "this" to the global object if it is NULL
    VM& vm = exec->vm();
    JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec);
    NakedPtr<Exception> evaluationException;
    JSValue returnValue = profiledEvaluate(globalObject->globalExec(), ProfilingReason::API, source, jsThisObject, evaluationException);

    if (evaluationException) {
        if (exception)
            *exception = toRef(exec, evaluationException->value());
#if ENABLE(REMOTE_INSPECTOR)
        // FIXME: If we have a debugger attached we could learn about ParseError exceptions through
        // ScriptDebugServer::sourceParsed and this path could produce a duplicate warning. The
        // Debugger path is currently ignored by inspector.
        // NOTE: If we don't have a debugger, this SourceCode will be forever lost to the inspector.
        // We could stash it in the inspector in case an inspector is ever opened.
        globalObject->inspectorController().reportAPIException(exec, evaluationException);
#endif
        return nullptr;
    }

    if (returnValue)
        return toRef(exec, returnValue);

    // happens, for example, when the only statement is an empty (';') statement
    return toRef(exec, jsUndefined());
}
Esempio n. 11
0
ExceptionInfo* FunctionExecutable::reparseExceptionInfo(JSGlobalData* globalData, ScopeChainNode* scopeChainNode, CodeBlock* codeBlock)
{
    RefPtr<FunctionBodyNode> newFunctionBody = globalData->parser->parse<FunctionBodyNode>(globalData, 0, 0, m_source);
    if (m_forceUsesArguments)
        newFunctionBody->setUsesArguments();
    newFunctionBody->finishParsing(m_parameters, m_name);

    ScopeChain scopeChain(scopeChainNode);
    JSGlobalObject* globalObject = scopeChain.globalObject();

    OwnPtr<CodeBlock> newCodeBlock(new FunctionCodeBlock(this, FunctionCode, source().provider(), source().startOffset()));
    globalData->functionCodeBlockBeingReparsed = newCodeBlock.get();

    OwnPtr<BytecodeGenerator> generator(new BytecodeGenerator(newFunctionBody.get(), globalObject->debugger(), scopeChain, newCodeBlock->symbolTable(), newCodeBlock.get()));
    generator->setRegeneratingForExceptionInfo(static_cast<FunctionCodeBlock*>(codeBlock));
    generator->generate();

    ASSERT(newCodeBlock->instructionCount() == codeBlock->instructionCount());

#if ENABLE(JIT)
    JITCode newJITCode = JIT::compile(globalData, newCodeBlock.get());
    ASSERT(newJITCode.size() == generatedJITCode().size());
#endif

    globalData->functionCodeBlockBeingReparsed = 0;

    return newCodeBlock->extractExceptionInfo();
}
EncodedJSValue jsTestNondeterministicNondeterministicWriteableAttr(ExecState* exec, JSObject* slotBase, EncodedJSValue thisValue, PropertyName)
{
    UNUSED_PARAM(exec);
    UNUSED_PARAM(slotBase);
    UNUSED_PARAM(thisValue);
    JSTestNondeterministic* castedThis = jsDynamicCast<JSTestNondeterministic*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        if (jsDynamicCast<JSTestNondeterministicPrototype*>(slotBase))
            return reportDeprecatedGetterError(*exec, "TestNondeterministic", "nondeterministicWriteableAttr");
        return throwGetterTypeError(*exec, "TestNondeterministic", "nondeterministicWriteableAttr");
    }
#if ENABLE(WEB_REPLAY)
    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    InputCursor& cursor = globalObject->inputCursor();
    static NeverDestroyed<const AtomicString> bindingName("TestNondeterministic.nondeterministicWriteableAttr", AtomicString::ConstructFromLiteral);
    if (cursor.isCapturing()) {
        String memoizedResult = castedThis->impl().nondeterministicWriteableAttr();
        cursor.appendInput<MemoizedDOMResult<String>>(bindingName.get().string(), memoizedResult, 0);
        JSValue result = jsStringWithCache(exec, memoizedResult);
        return JSValue::encode(result);
    }

    if (cursor.isReplaying()) {
        String memoizedResult;
        MemoizedDOMResultBase* input = cursor.fetchInput<MemoizedDOMResultBase>();
        if (input && input->convertTo<String>(memoizedResult)) {
            JSValue result = jsStringWithCache(exec, memoizedResult);
            return JSValue::encode(result);
        }
    }
#endif
    TestNondeterministic& impl = castedThis->impl();
    JSValue result = jsStringWithCache(exec, impl.nondeterministicWriteableAttr());
    return JSValue::encode(result);
}
// ECMA 15.3.2 The Function Constructor
JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
    // Functions need to have a space following the opening { due to for web compatibility
    // see https://bugs.webkit.org/show_bug.cgi?id=24350
    // We also need \n before the closing } to handle // comments at the end of the last line
    UString program;
    if (args.isEmpty())
        program = "(function() { \n})";
    else if (args.size() == 1)
        program = makeString("(function() { ", args.at(0).toString(exec), "\n})");
    else {
        StringBuilder builder;
        builder.append("(function(");
        builder.append(args.at(0).toString(exec));
        for (size_t i = 1; i < args.size() - 1; i++) {
            builder.append(",");
            builder.append(args.at(i).toString(exec));
        }
        builder.append(") { ");
        builder.append(args.at(args.size() - 1).toString(exec));
        builder.append("\n})");
        program = builder.build();
    }

    int errLine;
    UString errMsg;
    SourceCode source = makeSource(program, sourceURL, lineNumber);
    RefPtr<FunctionExecutable> function = FunctionExecutable::fromGlobalCode(functionName, exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);
    if (!function)
        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());

    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    ScopeChain scopeChain(globalObject, globalObject->globalData(), globalObject, exec->globalThisValue());
    return new (exec) JSFunction(exec, function, scopeChain.node());
}
Esempio n. 14
0
// ECMA 15.3.2 The Function Constructor
JSObject* constructFunction(ExecState* exec, const ArgList& args, const Identifier& functionName, const UString& sourceURL, int lineNumber)
{
    UString program;
    if (args.isEmpty())
        program = "(function(){})";
    else if (args.size() == 1)
        program = "(function(){" + args.at(exec, 0)->toString(exec) + "})";
    else {
        program = "(function(" + args.at(exec, 0)->toString(exec);
        for (size_t i = 1; i < args.size() - 1; i++)
            program += "," + args.at(exec, i)->toString(exec);
        program += "){" + args.at(exec, args.size() - 1)->toString(exec) + "})";
    }

    int errLine;
    UString errMsg;
    SourceCode source = makeSource(program, sourceURL, lineNumber);
    RefPtr<ProgramNode> programNode = exec->globalData().parser->parse<ProgramNode>(exec, exec->dynamicGlobalObject()->debugger(), source, &errLine, &errMsg);

    FunctionBodyNode* body = functionBody(programNode.get());
    if (!body)
        return throwError(exec, SyntaxError, errMsg, errLine, source.provider()->asID(), source.provider()->url());

    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    ScopeChain scopeChain(globalObject, globalObject->globalData(), exec->globalThisValue());
    return new (exec) JSFunction(exec, functionName, body, scopeChain.node());
}
Esempio n. 15
0
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
    ExecState* exec = toJS(ctx);
    exec->globalData().heap.registerThread();
    JSLock lock(exec);

    JSObject* jsThisObject = toJS(thisObject);

    // evaluate sets "this" to the global object if it is NULL
    JSGlobalObject* globalObject = exec->dynamicGlobalObject();
    SourceCode source = makeSource(script->ustring(), sourceURL->ustring(), startingLineNumber);
    Completion completion = evaluate(globalObject->globalExec(), globalObject->globalScopeChain(), source, jsThisObject);

    if (completion.complType() == Throw) {
        if (exception)
            *exception = toRef(completion.value());
        return 0;
    }
    
    if (completion.value())
        return toRef(completion.value());
    
    // happens, for example, when the only statement is an empty (';') statement
    return toRef(jsUndefined());
}
Esempio n. 16
0
JSObject* EvalExecutable::compileInternal(ExecState* exec, ScopeChainNode* scopeChainNode, JITCode::JITType jitType)
{
    SamplingRegion samplingRegion(jitType == JITCode::BaselineJIT ? "Baseline Compilation (TOTAL)" : "DFG Compilation (TOTAL)");
    
#if !ENABLE(JIT)
    UNUSED_PARAM(jitType);
#endif
    JSObject* exception = 0;
    JSGlobalData* globalData = &exec->globalData();
    JSGlobalObject* lexicalGlobalObject = exec->lexicalGlobalObject();
    
    if (!!m_evalCodeBlock && m_evalCodeBlock->canProduceCopyWithBytecode()) {
        BytecodeDestructionBlocker blocker(m_evalCodeBlock.get());
        OwnPtr<EvalCodeBlock> newCodeBlock = adoptPtr(new EvalCodeBlock(CodeBlock::CopyParsedBlock, *m_evalCodeBlock));
        newCodeBlock->setAlternative(static_pointer_cast<CodeBlock>(m_evalCodeBlock.release()));
        m_evalCodeBlock = newCodeBlock.release();
    } else {
        if (!lexicalGlobalObject->evalEnabled())
            return throwError(exec, createEvalError(exec, "Eval is disabled"));
        RefPtr<EvalNode> evalNode = parse<EvalNode>(globalData, lexicalGlobalObject, m_source, 0, isStrictMode() ? JSParseStrict : JSParseNormal, EvalNode::isFunctionNode ? JSParseFunctionCode : JSParseProgramCode, lexicalGlobalObject->debugger(), exec, &exception);
        if (!evalNode) {
            ASSERT(exception);
            return exception;
        }
        recordParse(evalNode->features(), evalNode->hasCapturedVariables(), evalNode->lineNo(), evalNode->lastLine());
        
        JSGlobalObject* globalObject = scopeChainNode->globalObject.get();
        
        OwnPtr<CodeBlock> previousCodeBlock = m_evalCodeBlock.release();
        ASSERT((jitType == JITCode::bottomTierJIT()) == !previousCodeBlock);
        m_evalCodeBlock = adoptPtr(new EvalCodeBlock(this, globalObject, source().provider(), scopeChainNode->localDepth(), previousCodeBlock.release()));
        OwnPtr<BytecodeGenerator> generator(adoptPtr(new BytecodeGenerator(evalNode.get(), scopeChainNode, m_evalCodeBlock->symbolTable(), m_evalCodeBlock.get(), !!m_evalCodeBlock->alternative() ? OptimizingCompilation : FirstCompilation)));
        if ((exception = generator->generate())) {
            m_evalCodeBlock = static_pointer_cast<EvalCodeBlock>(m_evalCodeBlock->releaseAlternative());
            evalNode->destroyData();
            return exception;
        }
        
        evalNode->destroyData();
        m_evalCodeBlock->copyPostParseDataFromAlternative();
    }

#if ENABLE(JIT)
    if (!jitCompileIfAppropriate(*globalData, m_evalCodeBlock, m_jitCodeForCall, jitType))
        return 0;
#endif

#if ENABLE(JIT)
#if ENABLE(INTERPRETER)
    if (!m_jitCodeForCall)
        Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
    else
#endif
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock) + m_jitCodeForCall.size());
#else
    Heap::heap(this)->reportExtraMemoryCost(sizeof(*m_evalCodeBlock));
#endif

    return 0;
}
EncodedJSValue doCallToJavaScript(void* executableAddress, ProtoCallFrame* protoCallFrame)
{
    CodeBlock* codeBlock = protoCallFrame->codeBlock();
    JSScope* scope = protoCallFrame->scope();
    JSObject* callee = protoCallFrame->callee();
    int argCountIncludingThis = protoCallFrame->argumentCountIncludingThis();
    int argCount = protoCallFrame->argumentCount();
    JSValue thisValue = protoCallFrame->thisValue();
    JSStack& stack = scope->vm()->interpreter->stack();

    CallFrame* newCallFrame = stack.pushFrame(codeBlock, scope, argCountIncludingThis, callee);
    if (UNLIKELY(!newCallFrame)) {
        JSGlobalObject* globalObject = scope->globalObject();
        ExecState* exec = globalObject->globalExec();
        return JSValue::encode(throwStackOverflowError(exec));
    }

    // Set the arguments for the callee:
    newCallFrame->setThisValue(thisValue);
    for (int i = 0; i < argCount; ++i)
        newCallFrame->setArgument(i, protoCallFrame->argument(i));

    JSValue result = execute(newCallFrame, executableAddress);

    stack.popFrame(newCallFrame);

    return JSValue::encode(result);
}
Esempio n. 18
0
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
{
    if (!ctx) {
        ASSERT_NOT_REACHED();
        return 0;
    }
    ExecState* exec = toJS(ctx);
    APIEntryShim entryShim(exec);

    JSObject* jsThisObject = toJS(thisObject);

    startingLineNumber = std::max(1, startingLineNumber);

    // evaluate sets "this" to the global object if it is NULL
    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
    SourceCode source = makeSource(script->string(), sourceURL->string(), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber::first()));

    JSValue evaluationException;
    JSValue returnValue = evaluate(globalObject->globalExec(), source, jsThisObject, &evaluationException);

    if (evaluationException) {
        if (exception)
            *exception = toRef(exec, evaluationException);
        return 0;
    }

    if (returnValue)
        return toRef(exec, returnValue);

    // happens, for example, when the only statement is an empty (';') statement
    return toRef(exec, jsUndefined());
}
Esempio n. 19
0
EncodedJSValue JSC_HOST_CALL IntlCollatorPrototypeGetterCompare(ExecState* exec)
{
    // 10.3.3 Intl.Collator.prototype.compare (ECMA-402 2.0)
    // 1. Let collator be this Collator object.
    IntlCollator* collator = jsDynamicCast<IntlCollator*>(exec->thisValue());
    if (!collator)
        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Intl.Collator.prototype.compare called on value that's not an object initialized as a Collator")));

    JSBoundFunction* boundCompare = collator->boundCompare();
    // 2. If collator.[[boundCompare]] is undefined,
    if (!boundCompare) {
        VM& vm = exec->vm();
        JSGlobalObject* globalObject = collator->globalObject();
        // a. Let F be a new built-in function object as defined in 11.3.4.
        // b. The value of F’s length property is 2.
        JSFunction* targetObject = JSFunction::create(vm, globalObject, 2, ASCIILiteral("compare"), IntlCollatorFuncCompare, NoIntrinsic);
        JSArray* boundArgs = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0);
        if (!boundArgs)
            return JSValue::encode(throwOutOfMemoryError(exec));

        // c. Let bc be BoundFunctionCreate(F, «this value»).
        boundCompare = JSBoundFunction::create(vm, globalObject, targetObject, collator, boundArgs, 2, ASCIILiteral("compare"));
        // d. Set collator.[[boundCompare]] to bc.
        collator->setBoundCompare(vm, boundCompare);
    }
    // 3. Return collator.[[boundCompare]].
    return JSValue::encode(boundCompare);
}
Esempio n. 20
0
void InspectorHeapAgent::getRemoteObject(ErrorString& errorString, int heapObjectId, const String* optionalObjectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result)
{
    // Prevent the cell from getting collected as we look it up.
    VM& vm = m_environment.vm();
    JSLockHolder lock(vm);
    DeferGC deferGC(vm.heap);

    unsigned heapObjectIdentifier = static_cast<unsigned>(heapObjectId);
    const Optional<HeapSnapshotNode> optionalNode = nodeForHeapObjectIdentifier(errorString, heapObjectIdentifier);
    if (!optionalNode)
        return;

    JSCell* cell = optionalNode->cell;
    Structure* structure = cell->structure(m_environment.vm());
    if (!structure) {
        errorString = ASCIILiteral("Unable to get object details");
        return;
    }

    JSGlobalObject* globalObject = structure->globalObject();
    if (!globalObject) {
        errorString = ASCIILiteral("Unable to get object details");
        return;
    }

    InjectedScript injectedScript = m_injectedScriptManager.injectedScriptFor(globalObject->globalExec());
    if (injectedScript.hasNoValue()) {
        errorString = ASCIILiteral("Unable to get object details - InjectedScript");
        return;
    }

    String objectGroup = optionalObjectGroup ? *optionalObjectGroup : String();
    result = injectedScript.wrapObject(cell, objectGroup, true);
}
EncodedJSValue JSC_HOST_CALL IntlNumberFormatPrototypeGetterFormat(ExecState* state)
{
    // 11.3.3 Intl.NumberFormat.prototype.format (ECMA-402 2.0)
    // 1. Let nf be this NumberFormat object.
    IntlNumberFormat* nf = jsDynamicCast<IntlNumberFormat*>(state->thisValue());

    // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns.
    if (!nf)
        nf = jsDynamicCast<IntlNumberFormat*>(state->thisValue().get(state, state->vm().propertyNames->intlSubstituteValuePrivateName));

    if (!nf)
        return JSValue::encode(throwTypeError(state, ASCIILiteral("Intl.NumberFormat.prototype.format called on value that's not an object initialized as a NumberFormat")));
    
    JSBoundFunction* boundFormat = nf->boundFormat();
    // 2. If nf.[[boundFormat]] is undefined,
    if (!boundFormat) {
        VM& vm = state->vm();
        JSGlobalObject* globalObject = nf->globalObject();
        // a. Let F be a new built-in function object as defined in 11.3.4.
        // b. The value of F’s length property is 1.
        JSFunction* targetObject = JSFunction::create(vm, globalObject, 1, ASCIILiteral("format"), IntlNumberFormatFuncFormatNumber, NoIntrinsic);
        JSArray* boundArgs = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0);
        if (!boundArgs)
            return JSValue::encode(throwOutOfMemoryError(state));

        // c. Let bf be BoundFunctionCreate(F, «this value»).
        boundFormat = JSBoundFunction::create(vm, state, globalObject, targetObject, nf, boundArgs, 1, ASCIILiteral("format"));
        if (vm.exception())
            return JSValue::encode(JSValue());
        // d. Set nf.[[boundFormat]] to bf.
        nf->setBoundFormat(vm, boundFormat);
    }
    // 3. Return nf.[[boundFormat]].
    return JSValue::encode(boundFormat);
}
Esempio n. 22
0
ModuleProgramExecutable* ModuleProgramExecutable::create(ExecState* exec, const SourceCode& source)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
    ModuleProgramExecutable* executable = new (NotNull, allocateCell<ModuleProgramExecutable>(*exec->heap())) ModuleProgramExecutable(exec, source);
    executable->finishCreation(exec->vm());

    ParserError error;
    DebuggerMode debuggerMode = globalObject->hasInteractiveDebugger() ? DebuggerOn : DebuggerOff;
    UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCode = vm.codeCache()->getUnlinkedModuleProgramCodeBlock(
        vm, executable, executable->source(), debuggerMode, error);

    if (globalObject->hasDebugger())
        globalObject->debugger()->sourceParsed(exec, executable->source().provider(), error.line(), error.message());

    if (error.isValid()) {
        throwVMError(exec, scope, error.toErrorObject(globalObject, executable->source()));
        return nullptr;
    }

    executable->m_unlinkedModuleProgramCodeBlock.set(exec->vm(), executable, unlinkedModuleProgramCode);

    executable->m_moduleEnvironmentSymbolTable.set(exec->vm(), executable, jsCast<SymbolTable*>(unlinkedModuleProgramCode->constantRegister(unlinkedModuleProgramCode->moduleEnvironmentSymbolTableConstantRegisterOffset()).get())->cloneScopePart(exec->vm()));

    return executable;
}
Esempio n. 23
0
// Evaluate some JavaScript code in the scope of this frame.
JSValue DebuggerCallFrame::evaluateWithScopeExtension(const String& script, JSObject* scopeExtensionObject, NakedPtr<Exception>& exception)
{
    ASSERT(isValid());
    CallFrame* callFrame = m_validMachineFrame;
    if (!callFrame)
        return jsUndefined();

    VM& vm = callFrame->vm();
    JSLockHolder lock(vm);
    auto catchScope = DECLARE_CATCH_SCOPE(vm);

    CodeBlock* codeBlock = nullptr;
    if (isTailDeleted())
        codeBlock = m_shadowChickenFrame.codeBlock;
    else
        codeBlock = callFrame->codeBlock();
    if (!codeBlock)
        return jsUndefined();
    
    DebuggerEvalEnabler evalEnabler(callFrame);

    EvalContextType evalContextType;
    
    if (isFunctionParseMode(codeBlock->unlinkedCodeBlock()->parseMode()))
        evalContextType = EvalContextType::FunctionEvalContext;
    else if (codeBlock->unlinkedCodeBlock()->codeType() == EvalCode)
        evalContextType = codeBlock->unlinkedCodeBlock()->evalContextType();
    else 
        evalContextType = EvalContextType::None;

    VariableEnvironment variablesUnderTDZ;
    JSScope::collectClosureVariablesUnderTDZ(scope()->jsScope(), variablesUnderTDZ);

    EvalExecutable* eval = DirectEvalExecutable::create(callFrame, makeSource(script), codeBlock->isStrictMode(), codeBlock->unlinkedCodeBlock()->derivedContextType(), codeBlock->unlinkedCodeBlock()->isArrowFunction(), evalContextType, &variablesUnderTDZ);
    if (UNLIKELY(catchScope.exception())) {
        exception = catchScope.exception();
        catchScope.clearException();
        return jsUndefined();
    }

    JSGlobalObject* globalObject = callFrame->vmEntryGlobalObject();
    if (scopeExtensionObject) {
        JSScope* ignoredPreviousScope = globalObject->globalScope();
        globalObject->setGlobalScopeExtension(JSWithScope::create(vm, globalObject, scopeExtensionObject, ignoredPreviousScope));
    }

    JSValue thisValue = this->thisValue();
    JSValue result = vm.interpreter->execute(eval, callFrame, thisValue, scope()->jsScope());
    if (UNLIKELY(catchScope.exception())) {
        exception = catchScope.exception();
        catchScope.clearException();
    }

    if (scopeExtensionObject)
        globalObject->clearGlobalScopeExtension();

    ASSERT(result);
    return result;
}
Esempio n. 24
0
JSJSGlobalObject::JSJSGlobalObject() {
  JSGlobalObject *pthis = (static_cast<JSGlobalObject *>(this));
  pthis->js_addInterface(JS_JSGlobalObject_GUID, pthis);
  pthis->js_addClassDescriptor(&JSJSGlobalObject::classDescriptor);
  pthis->js_addFunctionTable(JSJSGlobalObject::functionTable);
  jsSink = new JSJSGlobalObjectEventSink(this);
  jsSink->eventSink_registerTo(pthis);
}
ExecState* NPRuntimeObjectMap::globalExec() const
{
    JSGlobalObject* globalObject = this->globalObject();
    if (!globalObject)
        return 0;
    
    return globalObject->globalExec();
}
Esempio n. 26
0
static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* exec)
{
    JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
    if (!exec->argumentCount())
        return JSValue::encode(StringObject::create(exec, globalObject->stringObjectStructure()));
    
    return JSValue::encode(StringObject::create(exec, globalObject->stringObjectStructure(), exec->argument(0).toString(exec)));
}
Esempio n. 27
0
static EncodedJSValue JSC_HOST_CALL constructWeakSet(ExecState* exec)
{
    JSGlobalObject* globalObject = asInternalFunction(exec->callee())->globalObject();
    Structure* weakSetStructure = globalObject->weakSetStructure();
    JSWeakSet* weakSet = JSWeakSet::create(exec, weakSetStructure);
    JSValue iterable = exec->argument(0);
    if (iterable.isUndefinedOrNull())
        return JSValue::encode(weakSet);

    JSValue adderFunction = weakSet->JSObject::get(exec, exec->propertyNames().add);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    CallData adderFunctionCallData;
    CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
    if (adderFunctionCallType == CallTypeNone)
        return JSValue::encode(throwTypeError(exec));

    JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    CallData iteratorFunctionCallData;
    CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
    if (iteratorFunctionCallType == CallTypeNone)
        return JSValue::encode(throwTypeError(exec));

    ArgList iteratorFunctionArguments;
    JSValue iterator = call(exec, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    if (!iterator.isObject())
        return JSValue::encode(throwTypeError(exec));

    while (true) {
        JSValue next = iteratorStep(exec, iterator);
        if (exec->hadException())
            return JSValue::encode(jsUndefined());

        if (next.isFalse())
            return JSValue::encode(weakSet);

        JSValue nextValue = iteratorValue(exec, next);
        if (exec->hadException())
            return JSValue::encode(jsUndefined());

        MarkedArgumentBuffer arguments;
        arguments.append(nextValue);
        call(exec, adderFunction, adderFunctionCallType, adderFunctionCallData, weakSet, arguments);
        if (exec->hadException()) {
            iteratorClose(exec, iterator);
            return JSValue::encode(jsUndefined());
        }
    }
    RELEASE_ASSERT_NOT_REACHED();
    return JSValue::encode(weakSet);
}
Esempio n. 28
0
JSValue linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey, JSValue scriptFetcher)
{
    JSLockHolder lock(exec);
    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
    RELEASE_ASSERT(!exec->vm().isCollectorBusyOnCurrentThread());

    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
    return globalObject->moduleLoader()->linkAndEvaluateModule(exec, identifierToJSValue(exec->vm(), moduleKey), scriptFetcher);
}
Esempio n. 29
0
JSInternalPromise* linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey)
{
    JSLockHolder lock(exec);
    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
    RELEASE_ASSERT(!exec->vm().isCollectorBusy());

    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
    return globalObject->moduleLoader()->linkAndEvaluateModule(exec, identifierToJSValue(exec->vm(), moduleKey));
}
static ALWAYS_INLINE JSObject* constructObject(ExecState* exec)
{
    JSGlobalObject* globalObject = exec->callee()->globalObject();
    ArgList args(exec);
    JSValue arg = args.at(0);
    if (arg.isUndefinedOrNull())
        return constructEmptyObject(exec, globalObject->objectPrototype());
    return arg.toObject(exec, globalObject);
}