예제 #1
0
/* static */
void V8Runtime::bootstrap(Local<Context> context)
{
	Isolate* isolate = context->GetIsolate();
	EventEmitter::initTemplate(context);

	Local<Object> kroll = Object::New(isolate);
	krollGlobalObject.Reset(isolate, kroll);
	Local<Array> mc = Array::New(isolate);
	moduleContexts.Reset(isolate, mc);

	KrollBindings::initFunctions(kroll, context);

	SetMethod(isolate, kroll, "log", krollLog);
	// Move this into the EventEmitter::initTemplate call?
	Local<FunctionTemplate> eect = Local<FunctionTemplate>::New(isolate, EventEmitter::constructorTemplate);
	{
		v8::TryCatch tryCatch(isolate);
		Local<Function> eventEmitterConstructor;
		MaybeLocal<Function> maybeEventEmitterConstructor = eect->GetFunction(context);
		if (!maybeEventEmitterConstructor.ToLocal(&eventEmitterConstructor)) {
			titanium::V8Util::fatalException(isolate, tryCatch);
			return;
		}
		kroll->Set(NEW_SYMBOL(isolate, "EventEmitter"), eventEmitterConstructor);
	}

	kroll->Set(NEW_SYMBOL(isolate, "runtime"), STRING_NEW(isolate, "v8"));
	kroll->Set(NEW_SYMBOL(isolate, "DBG"), v8::Boolean::New(isolate, V8Runtime::DBG));
	kroll->Set(NEW_SYMBOL(isolate, "moduleContexts"), mc);

	LOG_TIMER(TAG, "Executing kroll.js");

	TryCatch tryCatch(isolate);
	Local<Value> result = V8Util::executeString(isolate, KrollBindings::getMainSource(isolate), STRING_NEW(isolate, "ti:/kroll.js"));

	if (tryCatch.HasCaught()) {
		V8Util::reportException(isolate, tryCatch, true);
	}
	if (!result->IsFunction()) {
		LOGF(TAG, "kroll.js result is not a function");
		V8Util::reportException(isolate, tryCatch, true);
	}

	// Add a reference to the global object
	Local<Object> global = context->Global();

	// Expose the global object as a property on itself
	// (Allows you to set stuff on `global` from anywhere in JavaScript.)
	global->Set(NEW_SYMBOL(isolate, "global"), global);

	Local<Function> mainFunction = result.As<Function>();
	Local<Value> args[] = { kroll };
	mainFunction->Call(context, global, 1, args);

	if (tryCatch.HasCaught()) {
		V8Util::reportException(isolate, tryCatch, true);
		LOGE(TAG, "Caught exception while bootstrapping Kroll");
	}
}
// https://html.spec.whatwg.org/multipage/scripting.html#upgrades
bool ScriptCustomElementDefinition::runConstructor(Element* element) {
  if (!m_scriptState->contextIsValid())
    return false;
  ScriptState::Scope scope(m_scriptState.get());
  v8::Isolate* isolate = m_scriptState->isolate();

  // Step 5 says to rethrow the exception; but there is no one to
  // catch it. The side effect is to report the error.
  v8::TryCatch tryCatch(isolate);
  tryCatch.SetVerbose(true);

  Element* result = runConstructor();

  // To report exception thrown from runConstructor()
  if (tryCatch.HasCaught())
    return false;

  // To report InvalidStateError Exception, when the constructor returns some
  // different object
  if (result != element) {
    const String& message =
        "custom element constructors must call super() first and must "
        "not return a different object";
    v8::Local<v8::Value> exception = V8ThrowException::createDOMException(
        m_scriptState->isolate(), InvalidStateError, message);
    dispatchErrorEvent(isolate, exception, constructor());
    return false;
  }

  return true;
}
예제 #3
0
void InjectedScript::getProperties(ErrorString* errorString, v8::Local<v8::Object> object, const String16& groupName, bool ownProperties, bool accessorPropertiesOnly, bool generatePreview, std::unique_ptr<Array<PropertyDescriptor>>* properties, Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails)
{
    v8::HandleScope handles(m_context->isolate());
    V8FunctionCall function(m_context->inspector(), m_context->context(), v8Value(), "getProperties");
    function.appendArgument(object);
    function.appendArgument(groupName);
    function.appendArgument(ownProperties);
    function.appendArgument(accessorPropertiesOnly);
    function.appendArgument(generatePreview);

    v8::TryCatch tryCatch(m_context->isolate());
    v8::Local<v8::Value> resultValue = function.callWithoutExceptionHandling();
    if (tryCatch.HasCaught()) {
        *exceptionDetails = createExceptionDetails(tryCatch.Message());
        // FIXME: make properties optional
        *properties = Array<PropertyDescriptor>::create();
        return;
    }

    std::unique_ptr<protocol::Value> protocolValue = toProtocolValue(m_context->context(), resultValue);
    if (hasInternalError(errorString, !protocolValue))
        return;
    protocol::ErrorSupport errors(errorString);
    std::unique_ptr<Array<PropertyDescriptor>> result = Array<PropertyDescriptor>::parse(protocolValue.get(), &errors);
    if (!hasInternalError(errorString, errors.hasErrors()))
        *properties = std::move(result);
}
예제 #4
0
Vector<String> Dictionary::getPropertyNames(
    ExceptionState& exceptionState) const {
  if (m_dictionaryObject.IsEmpty())
    return Vector<String>();

  v8::TryCatch tryCatch(isolate());
  v8::Local<v8::Array> propertyNames;
  if (!m_dictionaryObject->GetPropertyNames(v8Context())
           .ToLocal(&propertyNames)) {
    exceptionState.rethrowV8Exception(tryCatch.Exception());
    return Vector<String>();
  }

  Vector<String> names;
  for (uint32_t i = 0; i < propertyNames->Length(); ++i) {
    v8::Local<v8::String> key;
    if (!getStringValueInArray(v8Context(), propertyNames, i).ToLocal(&key)) {
      exceptionState.rethrowV8Exception(tryCatch.Exception());
      return Vector<String>();
    }
    V8StringResource<> stringKey(key);
    if (!stringKey.prepare(isolate(), exceptionState))
      return Vector<String>();

    names.push_back(stringKey);
  }

  return names;
}
bool V0CustomElementConstructorBuilder::validateOptions(const AtomicString& type, QualifiedName& tagName, ExceptionState& exceptionState)
{
    ASSERT(m_prototype.IsEmpty());

    v8::TryCatch tryCatch(m_scriptState->isolate());

    if (!m_scriptState->perContextData()) {
        // FIXME: This should generate an InvalidContext exception at a later point.
        V0CustomElementException::throwException(V0CustomElementException::ContextDestroyedCheckingPrototype, type, exceptionState);
        tryCatch.ReThrow();
        return false;
    }

    if (m_options.hasPrototype()) {
        ASSERT(m_options.prototype().isObject());
        m_prototype = m_options.prototype().v8Value().As<v8::Object>();
    } else {
        m_prototype = v8::Object::New(m_scriptState->isolate());
        v8::Local<v8::Object> basePrototype = m_scriptState->perContextData()->prototypeForType(&V8HTMLElement::wrapperTypeInfo);
        if (!basePrototype.IsEmpty()) {
            if (!v8CallBoolean(m_prototype->SetPrototype(m_scriptState->context(), basePrototype)))
                return false;
        }
    }

    AtomicString namespaceURI = HTMLNames::xhtmlNamespaceURI;
    if (hasValidPrototypeChainFor(&V8SVGElement::wrapperTypeInfo))
        namespaceURI = SVGNames::svgNamespaceURI;

    ASSERT(!tryCatch.HasCaught());

    AtomicString localName;

    if (m_options.hasExtends()) {
        localName = AtomicString(m_options.extends().lower());

        if (!Document::isValidName(localName)) {
            V0CustomElementException::throwException(V0CustomElementException::ExtendsIsInvalidName, type, exceptionState);
            tryCatch.ReThrow();
            return false;
        }
        if (V0CustomElement::isValidName(localName)) {
            V0CustomElementException::throwException(V0CustomElementException::ExtendsIsCustomElementName, type, exceptionState);
            tryCatch.ReThrow();
            return false;
        }
    } else {
        if (namespaceURI == SVGNames::svgNamespaceURI) {
            V0CustomElementException::throwException(V0CustomElementException::ExtendsIsInvalidName, type, exceptionState);
            tryCatch.ReThrow();
            return false;
        }
        localName = type;
    }

    ASSERT(!tryCatch.HasCaught());
    tagName = QualifiedName(nullAtom, localName, namespaceURI);
    return true;
}
static void dispatchErrorEvent(v8::Isolate* isolate,
                               v8::Local<v8::Value> exception,
                               v8::Local<v8::Object> constructor) {
  v8::TryCatch tryCatch(isolate);
  tryCatch.SetVerbose(true);
  V8ScriptRunner::throwException(
      isolate, exception, constructor.As<v8::Function>()->GetScriptOrigin());
}
예제 #7
0
v8::Local<v8::Value> V8ErrorHandler::callListenerFunction(
    ScriptState* scriptState,
    v8::Local<v8::Value> jsEvent,
    Event* event) {
  ASSERT(!jsEvent.IsEmpty());
  if (!event->hasInterface(EventNames::ErrorEvent))
    return V8EventListener::callListenerFunction(scriptState, jsEvent, event);

  ErrorEvent* errorEvent = static_cast<ErrorEvent*>(event);
  if (errorEvent->world() && errorEvent->world() != &world())
    return v8::Null(isolate());

  v8::Local<v8::Object> listener =
      getListenerObject(scriptState->getExecutionContext());
  if (listener.IsEmpty() || !listener->IsFunction())
    return v8::Null(isolate());

  v8::Local<v8::Function> callFunction =
      v8::Local<v8::Function>::Cast(listener);
  v8::Local<v8::Object> thisValue = scriptState->context()->Global();

  v8::Local<v8::Object> eventObject;
  if (!jsEvent->ToObject(scriptState->context()).ToLocal(&eventObject))
    return v8::Null(isolate());
  auto privateError = V8PrivateProperty::getErrorEventError(isolate());
  v8::Local<v8::Value> error =
      privateError.getOrUndefined(scriptState->context(), eventObject);
  if (error->IsUndefined())
    error = v8::Null(isolate());

  v8::Local<v8::Value> parameters[5] = {
      v8String(isolate(), errorEvent->message()),
      v8String(isolate(), errorEvent->filename()),
      v8::Integer::New(isolate(), errorEvent->lineno()),
      v8::Integer::New(isolate(), errorEvent->colno()), error};
  v8::TryCatch tryCatch(isolate());
  tryCatch.SetVerbose(true);
  v8::MaybeLocal<v8::Value> result;
  if (scriptState->getExecutionContext()->isWorkerGlobalScope()) {
    result = V8ScriptRunner::callFunction(
        callFunction, scriptState->getExecutionContext(), thisValue,
        WTF_ARRAY_LENGTH(parameters), parameters, isolate());
  } else {
    result = V8ScriptRunner::callFunction(
        callFunction, scriptState->getExecutionContext(), thisValue,
        WTF_ARRAY_LENGTH(parameters), parameters, isolate());
  }
  v8::Local<v8::Value> returnValue;
  if (!result.ToLocal(&returnValue))
    return v8::Null(isolate());

  return returnValue;
}
int V8Regex::match(const String16& string, int startFrom, int* matchLength) const
{
    if (matchLength)
        *matchLength = 0;

    if (m_regex.IsEmpty() || string.isEmpty())
        return -1;

    // v8 strings are limited to int.
    if (string.length() > INT_MAX)
        return -1;

    v8::Isolate* isolate = m_debugger->isolate();
    v8::HandleScope handleScope(isolate);
    v8::Local<v8::Context> context = m_debugger->regexContext();
    v8::MicrotasksScope microtasks(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
    v8::TryCatch tryCatch(isolate);

    v8::Local<v8::RegExp> regex = m_regex.Get(isolate);
    v8::Local<v8::Value> exec;
    if (!regex->Get(context, toV8StringInternalized(isolate, "exec")).ToLocal(&exec))
        return -1;
    v8::Local<v8::Value> argv[] = { toV8String(isolate, string.substring(startFrom)) };
    v8::Local<v8::Value> returnValue;
    if (!exec.As<v8::Function>()->Call(context, regex, WTF_ARRAY_LENGTH(argv), argv).ToLocal(&returnValue))
        return -1;

    // RegExp#exec returns null if there's no match, otherwise it returns an
    // Array of strings with the first being the whole match string and others
    // being subgroups. The Array also has some random properties tacked on like
    // "index" which is the offset of the match.
    //
    // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec

    ASSERT(!returnValue.IsEmpty());
    if (!returnValue->IsArray())
        return -1;

    v8::Local<v8::Array> result = returnValue.As<v8::Array>();
    v8::Local<v8::Value> matchOffset;
    if (!result->Get(context, toV8StringInternalized(isolate, "index")).ToLocal(&matchOffset))
        return -1;
    if (matchLength) {
        v8::Local<v8::Value> match;
        if (!result->Get(context, 0).ToLocal(&match))
            return -1;
        *matchLength = match.As<v8::String>()->Length();
    }

    return matchOffset.As<v8::Int32>()->Value() + startFrom;
}
bool ScriptCustomElementDefinitionBuilder::valueForName(
    const v8::Local<v8::Object>& object, const String& name,
    v8::Local<v8::Value>& value) const
{
    v8::Isolate* isolate = m_scriptState->isolate();
    v8::Local<v8::Context> context = m_scriptState->context();
    v8::Local<v8::String> nameString = v8String(isolate, name);
    v8::TryCatch tryCatch(isolate);
    if (!v8Call(object->Get(context, nameString), value, tryCatch)) {
        m_exceptionState.rethrowV8Exception(tryCatch.Exception());
        return false;
    }
    return true;
}
예제 #10
0
bool Dictionary::getInternal(const v8::Local<v8::Value>& key,
                             v8::Local<v8::Value>& result) const {
  if (m_dictionaryObject.IsEmpty())
    return false;

  if (!v8CallBoolean(m_dictionaryObject->Has(v8Context(), key)))
    return false;

  // Swallow a possible exception in v8::Object::Get().
  // TODO(bashi,yukishiino): Should rethrow the exception.
  // http://crbug.com/666661
  v8::TryCatch tryCatch(isolate());
  return m_dictionaryObject->Get(v8Context(), key).ToLocal(&result);
}
void V8AbstractEventListener::invokeEventHandler(ScriptState* scriptState, Event* event, v8::Local<v8::Value> jsEvent)
{
    if (!event->canBeDispatchedInWorld(world()))
        return;

    v8::Local<v8::Value> returnValue;
    {
        // Catch exceptions thrown in the event handler so they do not propagate to javascript code that caused the event to fire.
        v8::TryCatch tryCatch(isolate());
        tryCatch.SetVerbose(true);

        // Save the old 'event' property so we can restore it later.
        v8::Local<v8::Value> savedEvent = V8HiddenValue::getHiddenValue(scriptState, scriptState->context()->Global(), V8HiddenValue::event(isolate()));
        tryCatch.Reset();

        // Make the event available in the global object, so LocalDOMWindow can expose it.
        V8HiddenValue::setHiddenValue(scriptState, scriptState->context()->Global(), V8HiddenValue::event(isolate()), jsEvent);
        tryCatch.Reset();

        returnValue = callListenerFunction(scriptState, jsEvent, event);
        if (tryCatch.HasCaught())
            event->target()->uncaughtExceptionInEventHandler();

        if (!tryCatch.CanContinue()) { // Result of TerminateExecution().
            if (scriptState->executionContext()->isWorkerGlobalScope())
                toWorkerGlobalScope(scriptState->executionContext())->scriptController()->forbidExecution();
            return;
        }
        tryCatch.Reset();

        // Restore the old event. This must be done for all exit paths through this method.
        if (savedEvent.IsEmpty())
            V8HiddenValue::setHiddenValue(scriptState, scriptState->context()->Global(), V8HiddenValue::event(isolate()), v8::Undefined(isolate()));
        else
            V8HiddenValue::setHiddenValue(scriptState, scriptState->context()->Global(), V8HiddenValue::event(isolate()), savedEvent);
        tryCatch.Reset();
    }

    if (returnValue.IsEmpty())
        return;

    if (m_isAttribute && !returnValue->IsNull() && !returnValue->IsUndefined() && event->isBeforeUnloadEvent()) {
        TOSTRING_VOID(V8StringResource<>, stringReturnValue, returnValue);
        toBeforeUnloadEvent(event)->setReturnValue(stringReturnValue);
    }

    if (m_isAttribute && shouldPreventDefault(returnValue))
        event->preventDefault();
}
예제 #12
0
bool Dictionary::hasProperty(const StringView& key,
                             ExceptionState& exceptionState) const {
  if (m_dictionaryObject.IsEmpty())
    return false;

  v8::TryCatch tryCatch(m_isolate);
  bool hasKey = false;
  if (!m_dictionaryObject->Has(v8Context(), v8String(m_isolate, key))
           .To(&hasKey)) {
    exceptionState.rethrowV8Exception(tryCatch.Exception());
    return false;
  }

  return hasKey;
}
예제 #13
0
AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) {
  v8::Isolate* isolate = m_scriptState->isolate();
  v8::Local<v8::Function> lookupNamespaceURIFunc;
  v8::Local<v8::String> lookupNamespaceURIName =
      v8AtomicString(isolate, "lookupNamespaceURI");

  // Check if the resolver has a function property named lookupNamespaceURI.
  v8::Local<v8::Value> lookupNamespaceURI;
  if (m_resolver->Get(m_scriptState->context(), lookupNamespaceURIName)
          .ToLocal(&lookupNamespaceURI) &&
      lookupNamespaceURI->IsFunction())
    lookupNamespaceURIFunc = v8::Local<v8::Function>::Cast(lookupNamespaceURI);

  if (lookupNamespaceURIFunc.IsEmpty() && !m_resolver->IsFunction()) {
    LocalFrame* frame =
        toLocalDOMWindow(toDOMWindow(m_scriptState->context()))->frame();
    if (frame && frame->host())
      frame->console().addMessage(ConsoleMessage::create(
          JSMessageSource, ErrorMessageLevel,
          "XPathNSResolver does not have a lookupNamespaceURI method."));
    return nullAtom;
  }

  // Catch exceptions from calling the namespace resolver.
  v8::TryCatch tryCatch(isolate);
  tryCatch.SetVerbose(true);  // Print exceptions to console.

  const int argc = 1;
  v8::Local<v8::Value> argv[argc] = {v8String(isolate, prefix)};
  v8::Local<v8::Function> function =
      lookupNamespaceURIFunc.IsEmpty()
          ? v8::Local<v8::Function>::Cast(m_resolver)
          : lookupNamespaceURIFunc;

  v8::Local<v8::Value> retval;
  // Eat exceptions from namespace resolver and return an empty string. This
  // will most likely cause NamespaceError.
  if (!V8ScriptRunner::callFunction(
           function, toExecutionContext(m_scriptState->context()), m_resolver,
           argc, argv, isolate)
           .ToLocal(&retval))
    return nullAtom;

  TOSTRING_DEFAULT(V8StringResource<TreatNullAsNullString>, returnString,
                   retval, nullAtom);
  return returnString;
}
예제 #14
0
v8::Local<v8::Value> ScriptController::executeScriptAndReturnValue(v8::Local<v8::Context> context, const ScriptSourceCode& source, AccessControlStatus accessControlStatus, double* compilationFinishTime)
{
    TRACE_EVENT1("devtools.timeline", "EvaluateScript", "data", InspectorEvaluateScriptEvent::data(frame(), source.url().getString(), source.startPosition()));
    InspectorInstrumentation::NativeBreakpoint nativeBreakpoint(frame()->document(), "scriptFirstStatement", false);

    v8::Local<v8::Value> result;
    {
        V8CacheOptions v8CacheOptions(V8CacheOptionsDefault);
        if (frame()->settings())
            v8CacheOptions = frame()->settings()->v8CacheOptions();
        if (source.resource() && !source.resource()->response().cacheStorageCacheName().isNull()) {
            switch (frame()->settings()->v8CacheStrategiesForCacheStorage()) {
            case V8CacheStrategiesForCacheStorage::None:
                v8CacheOptions = V8CacheOptionsNone;
                break;
            case V8CacheStrategiesForCacheStorage::Normal:
                v8CacheOptions = V8CacheOptionsCode;
                break;
            case V8CacheStrategiesForCacheStorage::Default:
            case V8CacheStrategiesForCacheStorage::Aggressive:
                v8CacheOptions = V8CacheOptionsAlways;
                break;
            }
        }

        // Isolate exceptions that occur when compiling and executing
        // the code. These exceptions should not interfere with
        // javascript code we might evaluate from C++ when returning
        // from here.
        v8::TryCatch tryCatch(isolate());
        tryCatch.SetVerbose(true);

        v8::Local<v8::Script> script;
        if (!v8Call(V8ScriptRunner::compileScript(source, isolate(), accessControlStatus, v8CacheOptions), script, tryCatch))
            return result;

        if (compilationFinishTime) {
            *compilationFinishTime = WTF::monotonicallyIncreasingTime();
        }
        if (!v8Call(V8ScriptRunner::runCompiledScript(isolate(), script, frame()->document()), result, tryCatch))
            return result;
    }

    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "UpdateCounters", TRACE_EVENT_SCOPE_THREAD, "data", InspectorUpdateCountersEvent::data());

    return result;
}
void V8InjectedScriptHost::evaluateWithExceptionDetailsCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Isolate* isolate = info.GetIsolate();
    if (info.Length() < 1) {
        isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, "One argument expected.")));
        return;
    }

    v8::Local<v8::String> expression = info[0]->ToString(isolate);
    if (expression.IsEmpty()) {
        isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, "The argument must be a string.")));
        return;
    }

    ASSERT(isolate->InContext());
    v8::Local<v8::Object> wrappedResult = v8::Object::New(isolate);
    if (wrappedResult.IsEmpty())
        return;

    v8::TryCatch tryCatch(isolate);
    v8::Local<v8::Script> script;
    v8::Local<v8::Value> result;
    if (!v8Call(V8ScriptRunner::compileScript(expression, String(), String(), TextPosition(), isolate), script, tryCatch)) {
        setExceptionAsReturnValue(info, wrappedResult, tryCatch);
        return;
    }

    v8::Local<v8::Symbol> commandLineAPISymbolValue = commandLineAPISymbol(isolate);
    v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global();
    if (info.Length() >= 2 && info[1]->IsObject()) {
        v8::Local<v8::Object> commandLineAPI = info[1]->ToObject(isolate);
        global->Set(commandLineAPISymbolValue, commandLineAPI);
    }

    if (!v8Call(V8ScriptRunner::runCompiledScript(isolate, script, currentExecutionContext(isolate)), result, tryCatch)) {
        global->Delete(isolate->GetCurrentContext(), commandLineAPISymbolValue);
        setExceptionAsReturnValue(info, wrappedResult, tryCatch);
        return;
    }

    global->Delete(isolate->GetCurrentContext(), commandLineAPISymbolValue);
    wrappedResult->Set(v8::String::NewFromUtf8(isolate, "result"), result);
    wrappedResult->Set(v8::String::NewFromUtf8(isolate, "exceptionDetails"), v8::Undefined(isolate));
    v8SetReturnValue(info, wrappedResult);
}
예제 #16
0
/* static */
void V8Runtime::bootstrap(Local<Context> context)
{
	Isolate* isolate = context->GetIsolate();
	EventEmitter::initTemplate(context);

	Local<Object> global = Object::New(isolate);
	krollGlobalObject.Reset(isolate, global);
	Local<Array> mc = Array::New(isolate);
	moduleContexts.Reset(isolate, mc);

	KrollBindings::initFunctions(global, context);

	SetMethod(isolate, global, "log", krollLog);
	// Move this into the EventEmitter::initTemplate call?
	Local<FunctionTemplate> eect = Local<FunctionTemplate>::New(isolate, EventEmitter::constructorTemplate);
	global->Set(NEW_SYMBOL(isolate, "EventEmitter"), eect->GetFunction());

	global->Set(NEW_SYMBOL(isolate, "runtime"), STRING_NEW(isolate, "v8"));
	global->Set(NEW_SYMBOL(isolate, "DBG"), v8::Boolean::New(isolate, V8Runtime::DBG));
	global->Set(NEW_SYMBOL(isolate, "moduleContexts"), mc);

	LOG_TIMER(TAG, "Executing kroll.js");

	TryCatch tryCatch(isolate);
	Local<Value> result = V8Util::executeString(isolate, KrollBindings::getMainSource(isolate), STRING_NEW(isolate, "ti:/kroll.js"));

	if (tryCatch.HasCaught()) {
		V8Util::reportException(isolate, tryCatch, true);
	}
	if (!result->IsFunction()) {
		LOGF(TAG, "kroll.js result is not a function");
		V8Util::reportException(isolate, tryCatch, true);
	}

	Local<Function> mainFunction = result.As<Function>();
	Local<Value> args[] = { global };
	mainFunction->Call(context, context->Global(), 1, args);

	if (tryCatch.HasCaught()) {
		V8Util::reportException(isolate, tryCatch, true);
		LOGE(TAG, "Caught exception while bootstrapping Kroll");
	}
}
예제 #17
0
V8Regex::V8Regex(V8DebuggerImpl* debugger, const String16& pattern, bool caseSensitive, bool multiline)
    : m_debugger(debugger)
{
    v8::Isolate* isolate = m_debugger->isolate();
    v8::HandleScope handleScope(isolate);
    v8::Local<v8::Context> context = m_debugger->regexContext();
    v8::Context::Scope contextScope(context);
    v8::TryCatch tryCatch(isolate);

    unsigned flags = v8::RegExp::kNone;
    if (!caseSensitive)
        flags |= v8::RegExp::kIgnoreCase;
    if (multiline)
        flags |= v8::RegExp::kMultiline;

    v8::Local<v8::RegExp> regex;
    if (v8::RegExp::New(context, toV8String(isolate, pattern), static_cast<v8::RegExp::Flags>(flags)).ToLocal(&regex))
        m_regex.Reset(isolate, regex);
}
void ScriptCustomElementDefinition::runCallback(
    v8::Local<v8::Function> callback,
    Element* element,
    int argc,
    v8::Local<v8::Value> argv[]) {
  DCHECK(ScriptState::current(m_scriptState->isolate()) == m_scriptState);
  v8::Isolate* isolate = m_scriptState->isolate();

  // Invoke custom element reactions
  // https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions
  // If this throws any exception, then report the exception.
  v8::TryCatch tryCatch(isolate);
  tryCatch.SetVerbose(true);

  ExecutionContext* executionContext = m_scriptState->getExecutionContext();
  v8::Local<v8::Value> elementHandle =
      toV8(element, m_scriptState->context()->Global(), isolate);
  V8ScriptRunner::callFunction(callback, executionContext, elementHandle, argc,
                               argv, isolate);
}
v8::Local<v8::Value> JavaScriptCallFrame::evaluateWithExceptionDetails(v8::Local<v8::Value> expression, v8::Local<v8::Value> scopeExtension)
{
    v8::Local<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
    v8::Local<v8::Function> evalFunction = v8::Local<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "evaluate")));
    v8::Local<v8::Value> argv[] = {
        expression,
        scopeExtension
    };
    v8::TryCatch tryCatch(m_isolate);
    v8::Local<v8::Object> wrappedResult = v8::Object::New(m_isolate);
    v8::Local<v8::Value> result;
    if (V8ScriptRunner::callInternalFunction(evalFunction, callFrame, WTF_ARRAY_LENGTH(argv), argv, m_isolate).ToLocal(&result)) {
        wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), result);
        wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"), v8::Undefined(m_isolate));
    } else {
        wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "result"), tryCatch.Exception());
        wrappedResult->Set(v8::String::NewFromUtf8(m_isolate, "exceptionDetails"), createExceptionDetails(m_isolate, tryCatch.Message()));
    }
    return wrappedResult;
}
예제 #20
0
HashMap<String, String> Dictionary::getOwnPropertiesAsStringHashMap(
    ExceptionState& exceptionState) const {
  if (m_dictionaryObject.IsEmpty())
    return HashMap<String, String>();

  v8::TryCatch tryCatch(isolate());
  v8::Local<v8::Array> propertyNames;
  if (!m_dictionaryObject->GetOwnPropertyNames(v8Context())
           .ToLocal(&propertyNames)) {
    exceptionState.rethrowV8Exception(tryCatch.Exception());
    return HashMap<String, String>();
  }

  HashMap<String, String> ownProperties;
  for (uint32_t i = 0; i < propertyNames->Length(); ++i) {
    v8::Local<v8::String> key;
    if (!getStringValueInArray(v8Context(), propertyNames, i).ToLocal(&key)) {
      exceptionState.rethrowV8Exception(tryCatch.Exception());
      return HashMap<String, String>();
    }
    V8StringResource<> stringKey(key);
    if (!stringKey.prepare(isolate(), exceptionState))
      return HashMap<String, String>();

    v8::Local<v8::Value> value;
    if (!m_dictionaryObject->Get(v8Context(), key).ToLocal(&value)) {
      exceptionState.rethrowV8Exception(tryCatch.Exception());
      return HashMap<String, String>();
    }
    V8StringResource<> stringValue(value);
    if (!stringValue.prepare(isolate(), exceptionState))
      return HashMap<String, String>();

    if (!static_cast<const String&>(stringKey).isEmpty())
      ownProperties.set(stringKey, stringValue);
  }

  return ownProperties;
}
void V8InjectedScriptHost::evalCallback(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Isolate* isolate = info.GetIsolate();
    if (info.Length() < 1) {
        isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, "One argument expected.")));
        return;
    }

    v8::Local<v8::String> expression = info[0]->ToString(isolate);
    if (expression.IsEmpty()) {
        isolate->ThrowException(v8::Exception::Error(v8::String::NewFromUtf8(isolate, "The argument must be a string.")));
        return;
    }

    ASSERT(isolate->InContext());
    v8::TryCatch tryCatch(isolate);
    v8::Local<v8::Value> result;
    if (!v8Call(V8ScriptRunner::compileAndRunInternalScript(expression, info.GetIsolate()), result, tryCatch)) {
        v8SetReturnValue(info, tryCatch.ReThrow());
        return;
    }
    v8SetReturnValue(info, result);
}
HTMLElement* ScriptCustomElementDefinition::createElementSync(
    Document& document,
    const QualifiedName& tagName,
    ExceptionState& exceptionState) {
  DCHECK(ScriptState::current(m_scriptState->isolate()) == m_scriptState);

  // Create an element
  // https://dom.spec.whatwg.org/#concept-create-element
  // 6. If definition is non-null
  // 6.1. If the synchronous custom elements flag is set:
  // 6.1.2. Set result to Construct(C). Rethrow any exceptions.

  // Create an element and push to the construction stack.
  // V8HTMLElement::constructorCustom() can only refer to
  // window.document(), but it is different from the document here
  // when it is an import document.  This is not exactly what the
  // spec defines, but the public behavior matches to the spec.
  Element* element = createElementForConstructor(document);
  {
    ConstructionStackScope constructionStackScope(this, element);
    v8::TryCatch tryCatch(m_scriptState->isolate());
    element = runConstructor();
    if (tryCatch.HasCaught()) {
      exceptionState.rethrowV8Exception(tryCatch.Exception());
      return nullptr;
    }
  }

  // 6.1.3. through 6.1.9.
  checkConstructorResult(element, document, tagName, exceptionState);
  if (exceptionState.hadException())
    return nullptr;

  DCHECK_EQ(element->getCustomElementState(), CustomElementState::Custom);
  return toHTMLElement(element);
}
예제 #23
0
// https://html.spec.whatwg.org/multipage/dom.html#html-element-constructors
void V8HTMLConstructor::htmlConstructor(
    const v8::FunctionCallbackInfo<v8::Value>& info,
    const WrapperTypeInfo& wrapperTypeInfo,
    const HTMLElementType elementInterfaceName) {
  TRACE_EVENT0("blink", "HTMLConstructor");
  DCHECK(info.IsConstructCall());

  v8::Isolate* isolate = info.GetIsolate();
  ScriptState* scriptState = ScriptState::current(isolate);
  v8::Local<v8::Value> newTarget = info.NewTarget();

  if (!scriptState->contextIsValid()) {
    V8ThrowException::throwError(isolate, "The context has been destroyed");
    return;
  }

  if (!RuntimeEnabledFeatures::customElementsV1Enabled() ||
      !scriptState->world().isMainWorld()) {
    V8ThrowException::throwTypeError(isolate, "Illegal constructor");
    return;
  }

  // 2. If NewTarget is equal to the active function object, then
  // throw a TypeError and abort these steps.
  v8::Local<v8::Function> activeFunctionObject =
      scriptState->perContextData()->constructorForType(
          &V8HTMLElement::wrapperTypeInfo);
  if (newTarget == activeFunctionObject) {
    V8ThrowException::throwTypeError(isolate, "Illegal constructor");
    return;
  }

  LocalDOMWindow* window = scriptState->domWindow();
  CustomElementRegistry* registry = window->customElements();

  // 3. Let definition be the entry in registry with constructor equal to
  // NewTarget.
  // If there is no such definition, then throw a TypeError and abort these
  // steps.
  ScriptCustomElementDefinition* definition =
      ScriptCustomElementDefinition::forConstructor(scriptState, registry,
                                                    newTarget);
  if (!definition) {
    V8ThrowException::throwTypeError(isolate, "Illegal constructor");
    return;
  }

  const AtomicString& localName = definition->descriptor().localName();
  const AtomicString& name = definition->descriptor().name();

  if (localName == name) {
    // Autonomous custom element
    // 4.1. If the active function object is not HTMLElement, then throw a
    // TypeError
    if (!V8HTMLElement::wrapperTypeInfo.equals(&wrapperTypeInfo)) {
      V8ThrowException::throwTypeError(isolate,
                                       "Illegal constructor: autonomous custom "
                                       "elements must extend HTMLElement");
      return;
    }
  } else {
    // Customized built-in element
    // 5. If local name is not valid for interface, throw TypeError
    if (htmlElementTypeForTag(localName) != elementInterfaceName) {
      V8ThrowException::throwTypeError(isolate,
                                       "Illegal constructor: localName does "
                                       "not match the HTML element interface");
      return;
    }
  }

  ExceptionState exceptionState(isolate, ExceptionState::ConstructionContext,
                                "HTMLElement");
  v8::TryCatch tryCatch(isolate);

  // 6. Let prototype be Get(NewTarget, "prototype"). Rethrow any exceptions.
  v8::Local<v8::Value> prototype;
  v8::Local<v8::String> prototypeString = v8AtomicString(isolate, "prototype");
  if (!v8Call(newTarget.As<v8::Object>()->Get(scriptState->context(),
                                              prototypeString),
              prototype)) {
    return;
  }

  // 7. If Type(prototype) is not Object, then: ...
  if (!prototype->IsObject()) {
    if (V8PerContextData* perContextData = V8PerContextData::from(
            newTarget.As<v8::Object>()->CreationContext())) {
      prototype =
          perContextData->prototypeForType(&V8HTMLElement::wrapperTypeInfo);
    } else {
      V8ThrowException::throwError(isolate, "The context has been destroyed");
      return;
    }
  }

  // 8. If definition's construction stack is empty...
  Element* element;
  if (definition->constructionStack().isEmpty()) {
    // This is an element being created with 'new' from script
    element = definition->createElementForConstructor(*window->document());
  } else {
    element = definition->constructionStack().last();
    if (element) {
      // This is an element being upgraded that has called super
      definition->constructionStack().last().clear();
    } else {
      // During upgrade an element has invoked the same constructor
      // before calling 'super' and that invocation has poached the
      // element.
      exceptionState.throwDOMException(InvalidStateError,
                                       "this instance is already constructed");
      return;
    }
  }
  const WrapperTypeInfo* wrapperType = element->wrapperTypeInfo();
  v8::Local<v8::Object> wrapper = V8DOMWrapper::associateObjectWithWrapper(
      isolate, element, wrapperType, info.Holder());
  // If the element had a wrapper, we now update and return that
  // instead.
  v8SetReturnValue(info, wrapper);

  // 11. Perform element.[[SetPrototypeOf]](prototype). Rethrow any exceptions.
  // Note: I don't think this prototype set *can* throw exceptions.
  wrapper->SetPrototype(scriptState->context(), prototype.As<v8::Object>())
      .ToChecked();
}