コード例 #1
0
AdblockPlus::JsValuePtr AdblockPlus::JsValue::Call(const JsValueList& params, JsValuePtr thisPtr) const
{
  if (!IsFunction())
    throw new std::runtime_error("Attempting to call a non-function");

  const JsContext context(jsEngine);
  if (!thisPtr)
  {
	  v8::Local<v8::Context> localContext = v8::Local<v8::Context>::New(jsEngine->GetIsolate(), *jsEngine->context);
    thisPtr = JsValuePtr(new JsValue(jsEngine, localContext->Global()));
  }
  if (!thisPtr->IsObject())
    throw new std::runtime_error("`this` pointer has to be an object");
  v8::Local<v8::Object> thisObj = v8::Local<v8::Object>::Cast(thisPtr->UnwrapValue());

  std::vector<v8::Handle<v8::Value>> argv;
  for (JsValueList::const_iterator it = params.begin(); it != params.end(); ++it)
    argv.push_back((*it)->UnwrapValue());

  const v8::TryCatch tryCatch;
  v8::Local<v8::Function> func = v8::Local<v8::Function>::Cast(UnwrapValue());
  v8::Local<v8::Value> result = func->Call(thisObj, argv.size(),
      argv.size() ? &argv.front() : 0);

  if (tryCatch.HasCaught())
    throw JsError(tryCatch.Exception(), tryCatch.Message());

  return JsValuePtr(new JsValue(jsEngine, result));
}
コード例 #2
0
ファイル: parser.cpp プロジェクト: zapta/misc
void ProcessNextChar(char c) {
  if (c == '\n') {
    state = jsBegin;  // abandon current parse (if any) and start again
    return;
  }

  switch (state) {
    case jsBegin:  // initial state, expecting '{'
      if (c == '{') {
        parser_watcher::StartReceivedMessage();
        state = jsExpectId;
        fieldVal.clear();
        fieldId.clear();
        arrayDepth = 0;
      }
      break;

    case jsExpectId:  // expecting a quoted ID
      switch (c) {
        case ' ':  // ignore space
          break;
        case '"':
          state = jsId;
          break;
        case '}':  // empty object, or extra comma at end of field list
          RemoveLastId();
          if (fieldId.size() == 0) {
            // TODO: should we report this to the monitor as an error?
            parser_watcher::EndReceivedMessage();
            state = jsBegin;
          } else {
            RemoveLastIdChar();
            state = jsEndVal;
          }
          break;
        default:
          state = JsError();
          break;
      }
      break;

    case jsId:  // expecting an identifier, or in the middle of one
      switch (c) {
        case '"':
          state = jsHadId;
          break;
        default:
          if (c < ' ') {
            state = JsError();
          } else if (c != ':' && c != '^') {
            if (!fieldId.add(c)) {
              state = JsError();
            }
          }
          break;
      }
      break;

    case jsHadId:  // had a quoted identifier, expecting ':'
      switch (c) {
        case ':':
          state = jsVal;
          break;
        case ' ':
          break;
        default:
          state = JsError();
          break;
      }
      break;

    case jsVal:  // had ':' or ':[', expecting value
      switch (c) {
        case ' ':
          break;
        case '"':
          fieldVal.clear();
          state = jsStringVal;
          break;
        case '[':
          if (arrayDepth < MAX_ARRAY_NESTING && fieldId.add('^')) {
            arrayIndices[arrayDepth] = 0;  // start an array
            ++arrayDepth;
          } else {
            state = JsError();
          }
          break;
        case ']':
          if (InArray()) {
            EndArray();  // empty array
            state = jsEndVal;
          } else {
            state = JsError();  // ']' received without a matching '[' first
          }
          break;
        case '-':
          fieldVal.clear();
          // TODO: an report error to the watcher
          state = (fieldVal.add(c)) ? jsNegIntVal : JsError();
          break;
        case '{':  // start of a nested object
                   // TODO: report an error to the watcher
          state = (fieldId.add(':')) ? jsExpectId : JsError();
          break;
        default:
          if (c >= '0' && c <= '9') {
            fieldVal.clear();
            fieldVal.add(c);  // must succeed because we just cleared fieldVal
            state = jsIntVal;
            break;
          } else {
            state = JsError();
          }
      }
      break;

    case jsStringVal:  // just had '"' and expecting a string value
      switch (c) {
        case '"':
          ConvertUnicode();
          ProcessField();
          state = jsEndVal;
          break;
        case '\\':
          state = jsStringEscape;
          break;
        default:
          if (c < ' ') {
            state = JsError();
          } else {
            fieldVal.add(c);  // ignore any error so that long string parameters
                              // just get truncated
          }
          break;
      }
      break;

    case jsStringEscape:  // just had backslash in a string
      if (!fieldVal.full()) {
        switch (c) {
          case '"':
          case '\\':
          case '/':
            if (!fieldVal.add(c)) {
              state = JsError();
            }
            break;
          case 'n':
          case 't':
            if (!fieldVal.add(' '))  // replace newline and tab by space
            {
              // parser_watcher::ProcessError();

              state = JsError();
            }
            break;
          case 'b':
          case 'f':
          case 'r':
          default:
            break;
        }
      }
      state = jsStringVal;
      break;

    case jsNegIntVal:  // had '-' so expecting a integer value
                       // TODO: report an error to the watcher
      state = (c >= '0' && c <= '9' && fieldVal.add(c)) ? jsIntVal : JsError();
      break;

    case jsIntVal:  // receiving an integer value
      switch (c) {
        case '.':
          state = (fieldVal.add(c)) ? jsFracVal : JsError();
          break;
        case ',':
          ProcessField();
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            fieldVal.clear();
            state = jsVal;
          } else {
            RemoveLastId();
            state = jsExpectId;
          }
          break;
        case ']':
          if (InArray()) {
            ProcessField();
            ++arrayIndices[arrayDepth - 1];
            EndArray();
            state = jsEndVal;
          } else {
            state = JsError();
          }
          break;
        case '}':
          if (InArray()) {
            state = JsError();
          } else {
            ProcessField();
            RemoveLastId();
            if (fieldId.size() == 0) {
              parser_watcher::EndReceivedMessage();
              state = jsBegin;
            } else {
              RemoveLastIdChar();
              state = jsEndVal;
            }
          }
          break;
        default:
          if (!(c >= '0' && c <= '9' && fieldVal.add(c))) {
            state = JsError();
          }
          break;
      }
      break;

    case jsFracVal:  // receiving a fractional value
      switch (c) {
        case ',':
          ProcessField();
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            state = jsVal;
          } else {
            RemoveLastId();
            state = jsExpectId;
          }
          break;
        case ']':
          if (InArray()) {
            ProcessField();
            ++arrayIndices[arrayDepth - 1];
            EndArray();
            state = jsEndVal;
          } else {
            state = JsError();
          }
          break;
        case '}':
          if (InArray()) {
            state = JsError();
          } else {
            ProcessField();
            RemoveLastId();
            if (fieldId.size() == 0) {
              parser_watcher::EndReceivedMessage();
              state = jsBegin;
            } else {
              RemoveLastIdChar();
              state = jsEndVal;
            }
          }
          break;
        default:
          if (!(c >= '0' && c <= '9' && fieldVal.add(c))) {
            state = JsError();
          }
          break;
      }
      break;

    case jsEndVal:  // had the end of a string or array value, expecting comma
                    // or ] or }
      switch (c) {
        case ',':
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            fieldVal.clear();
            state = jsVal;
          } else {
            RemoveLastId();
            state = jsExpectId;
          }
          break;
        case ']':
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            EndArray();
          } else {
            state = JsError();
          }
          break;
        case '}':
          if (InArray()) {
            state = JsError();
          } else {
            RemoveLastId();
            if (fieldId.size() == 0) {
              parser_watcher::EndReceivedMessage();
              state = jsBegin;
            } else {
              RemoveLastIdChar();
              // state = jsEndVal;     // not needed, state == jsEndVal already
            }
          }
          break;
        default:
          break;
      }
      break;

    case jsError:
      // Ignore all characters. State will be reset to jsBegin at the start of
      // this function when we receive a newline.
      break;
  }
}