CompletionType evaluate() { Value* value = getScopeChain()->get("iid"); if (!value->isString()) { throw getErrorInstance("TypeError"); } const char* iid = value->toString().c_str(); Reflect::Interface interface; try { interface = es::getInterface(iid); } catch (...) { throw getErrorInstance("TypeError"); } // Construct Interface Object ObjectValue* object = new ObjectValue; object->setCode(new InterfaceConstructor(object, iid)); object->setPrototype(prototype); return CompletionType(CompletionType::Return, object, ""); }
std::string decode(std::string& uri, const std::string& reserved) { std::string result = ""; int seq = 0; int k; for (k = 0; k < uri.length(); ++k) { char c = uri[k]; if (c == '%') { if (uri.length() < k + 2) { throw getErrorInstance("URIError"); } c = getCode(uri, k); k += 2; if (seq == 0) { while ((c & 1 << (7-seq)) && seq < 8) { ++seq; } if (0 < seq) { --seq; } } else if (0 < seq) { --seq; } if (reserved.find(c) != std::string::npos) { result += uri[k-2]; result += uri[k-1]; result += uri[k]; continue; } } else if (seq) { throw getErrorInstance("URIError"); } result += c; } return result; }
std::string encode(std::string& uri, const std::string& unescapedSet) { int k; std::string result = ""; for (k = 0; k < uri.length(); ++k) { char c = uri[k]; if (unescapedSet.find(c) == std::string::npos) { int seq = 0; while ((c & 1 << (7-seq))) { if (4 < ++seq) { throw getErrorInstance("URIError"); } } if (seq == 0 && isUnescaped(c, unescapedSet)) { result += c; continue; } char escaped[4]; while (k < uri.length()) { sprintf(escaped, "%%%02X", static_cast<u8>(uri[k])); result += escaped; if (--seq <= 0) { break; } ++k; } if (0 < seq) { throw getErrorInstance("URIError"); } } else { result += c; } } return result; }
CompletionType evaluate() { InterfacePointerValue* object = dynamic_cast<InterfacePointerValue*>(getThis()); if (!object) { throw getErrorInstance("TypeError"); } ListValue* list = static_cast<ListValue*>(getScopeChain()->get("arguments")); Register<Value> value = invoke(iid, number, object, list); return CompletionType(CompletionType::Return, value, ""); }
ObjectValue* StringValue::toObject() { // Create a new String object ObjectValue* string = dynamic_cast<ObjectValue*>(getGlobal()->get("String")); if (!string || !string->getCode()) { throw getErrorInstance("TypeError"); } Register<ListValue> list = new ListValue; list->push(this); return string->construct(list); };
// Query interface for this interface. CompletionType evaluate() { if (constructor->hasInstance(getThis())) { // Constructor Object* constructor = es::getConstructor(iid.c_str()); if (!constructor) { throw getErrorInstance("TypeError"); } // TODO: Currently only the default constructor is supported std::string ciid = iid; ciid += "::Constructor"; Value* value = invoke(ciid.c_str(), 0, reinterpret_cast<InterfaceMethod**>(constructor), 0); return CompletionType(CompletionType::Return, value, ""); } else { // Cast InterfacePointerValue* self = dynamic_cast<InterfacePointerValue*>(getScopeChain()->get("object")); if (!self) { throw getErrorInstance("TypeError"); } Object* object; object = self->getObject(); if (!object || !(object = reinterpret_cast<Object*>(object->queryInterface(iid.c_str())))) { // We should throw an error in case called by a new expression. throw getErrorInstance("TypeError"); } ObjectValue* value = new InterfacePointerValue(object); value->setPrototype(prototype); return CompletionType(CompletionType::Return, value, ""); } }
static Value* invoke(const char* iid, int number, InterfacePointerValue* object, ListValue* list) { InterfaceMethod** self = reinterpret_cast<InterfaceMethod**>(object->getObject()); if (!self) { throw getErrorInstance("TypeError"); } Value* value = invoke(iid, number, self, list); if (strcmp(iid, Object::iid()) == 0 && number == 2) // Object::release() { object->clearObject(); } return value; }
void MsgHandler::initOutputOptions(bool gui) { OptionsCont& oc = OptionsCont::getOptions(); //getMessageInstance()->report2cout(!gui && oc.getBool("verbose")); getMessageInstance()->report2cout(true); getWarningInstance()->report2cerr(!gui && !oc.getBool("suppress-warnings")); // build the logger if possible if (oc.isSet("log-file")) { try { OutputDevice *logFile = &OutputDevice::getDevice(oc.getString("log-file")); getErrorInstance()->addRetriever(logFile); getWarningInstance()->addRetriever(logFile); getMessageInstance()->addRetriever(logFile); } catch (IOError &) { throw ProcessError("Could not build logging file '" + oc.getString("log-file") + "'"); } } if (oc.isSet("message-log")) { try { OutputDevice *logFile = &OutputDevice::getDevice(oc.getString("message-log")); getMessageInstance()->addRetriever(logFile); } catch (IOError &) { throw ProcessError("Could not build logging file '" + oc.getString("message-log") + "'"); } } if (oc.isSet("error-log")) { try { OutputDevice *logFile = &OutputDevice::getDevice(oc.getString("error-log")); getErrorInstance()->addRetriever(logFile); getWarningInstance()->addRetriever(logFile); } catch (IOError &) { throw ProcessError("Could not build logging file '" + oc.getString("error-log") + "'"); } } }
int getInt(char hex) { if (!isxdigit(hex)) { return -1; } if ('0' <= hex && hex <= '9') { return hex - '0'; } if ('a' <= hex && hex <= 'f') { return hex - 'a' + 0x0A; } if ('A' <= hex && hex <= 'F') { return hex - 'A' + 0x0A; } throw getErrorInstance("URIError"); }
static Value* invoke(const char* iid, int number, InterfaceMethod** self, ListValue* list) { if (!self) { throw getErrorInstance("TypeError"); } Reflect::Interface interface = es::getInterface(iid); Reflect::Method method(interface.getMethod(number)); PRINTF("invoke %s.%s(%p)\n", interface.getName().c_str(), method.getName().c_str(), self); // Set up parameters Any argv[9]; Any* argp = argv; int ext = 0; // extra parameter count // Set this *argp++ = Any(reinterpret_cast<intptr_t>(self)); // In the following implementation, we assume no out nor inout attribute is // used for parameters. Reflect::Type returnType = method.getReturnType(); switch (returnType.getType()) { case Reflect::kAny: // Any op(void* buf, int len, ...); // FALL THROUGH case Reflect::kString: // const char* op(xxx* buf, int len, ...); *argp++ = Any(reinterpret_cast<intptr_t>(heap)); *argp++ = Any(sizeof(heap)); break; case Reflect::kSequence: // int op(xxx* buf, int len, ...); *argp++ = Any(reinterpret_cast<intptr_t>(heap)); ++ext; *argp++ = Any(static_cast<int32_t>(((*list)[0])->toNumber())); break; case Reflect::kArray: // void op(xxx[x] buf, ...); *argp++ = Any(reinterpret_cast<intptr_t>(heap)); break; } Reflect::Parameter param = method.listParameter(); for (int i = ext; param.next(); ++i, ++argp) { Reflect::Type type(param.getType()); Value* value = (*list)[i]; switch (type.getType()) { case Reflect::kAny: // Any variant, ... switch (value->getType()) { case Value::BoolType: *argp = Any(static_cast<bool>(value->toBoolean())); break; case Value::StringType: *argp = Any(value->toString().c_str()); break; case Value::NumberType: *argp = Any(static_cast<double>(value->toNumber())); break; case Value::ObjectType: if (InterfacePointerValue* unknown = dynamic_cast<InterfacePointerValue*>(value)) { *argp = Any(unknown->getObject()); } else { // XXX expose ECMAScript object *argp = Any(static_cast<Object*>(0)); } break; default: *argp = Any(); break; } argp->makeVariant(); break; case Reflect::kSequence: // xxx* buf, int len, ... // XXX Assume sequence<octet> now... *argp++ = Any(reinterpret_cast<intptr_t>(value->toString().c_str())); value = (*list)[++i]; *argp = Any(static_cast<int32_t>(value->toNumber())); break; case Reflect::kString: *argp = Any(value->toString().c_str()); break; case Reflect::kArray: // void op(xxx[x] buf, ...); // XXX expand data break; case Reflect::kObject: if (InterfacePointerValue* unknown = dynamic_cast<InterfacePointerValue*>(value)) { *argp = Any(unknown->getObject()); } else { *argp = Any(static_cast<Object*>(0)); } break; case Reflect::kBoolean: *argp = Any(static_cast<bool>(value->toBoolean())); break; case Reflect::kPointer: *argp = Any(static_cast<intptr_t>(value->toNumber())); break; case Reflect::kShort: *argp = Any(static_cast<int16_t>(value->toNumber())); break; case Reflect::kLong: *argp = Any(static_cast<int32_t>(value->toNumber())); break; case Reflect::kOctet: *argp = Any(static_cast<uint8_t>(value->toNumber())); break; case Reflect::kUnsignedShort: *argp = Any(static_cast<uint16_t>(value->toNumber())); break; case Reflect::kUnsignedLong: *argp = Any(static_cast<uint32_t>(value->toNumber())); break; case Reflect::kLongLong: *argp = Any(static_cast<int64_t>(value->toNumber())); break; case Reflect::kUnsignedLongLong: *argp = Any(static_cast<uint64_t>(value->toNumber())); break; case Reflect::kFloat: *argp = Any(static_cast<float>(value->toNumber())); break; case Reflect::kDouble: *argp = Any(static_cast<double>(value->toNumber())); break; default: break; } } // Invoke method Register<Value> value; unsigned methodNumber = interface.getInheritedMethodCount() + number; int argc = argp - argv; switch (returnType.getType()) { case Reflect::kAny: { Any result = apply(argc, argv, (Any (*)()) ((*self)[methodNumber])); switch (result.getType()) { case Any::TypeVoid: value = NullValue::getInstance(); break; case Any::TypeBool: value = BoolValue::getInstance(static_cast<bool>(result)); break; case Any::TypeOctet: value = new NumberValue(static_cast<uint8_t>(result)); break; case Any::TypeShort: value = new NumberValue(static_cast<int16_t>(result)); break; case Any::TypeUnsignedShort: value = new NumberValue(static_cast<uint16_t>(result)); break; case Any::TypeLong: value = new NumberValue(static_cast<int32_t>(result)); break; case Any::TypeUnsignedLong: value = new NumberValue(static_cast<uint32_t>(result)); break; case Any::TypeLongLong: value = new NumberValue(static_cast<int64_t>(result)); break; case Any::TypeUnsignedLongLong: value = new NumberValue(static_cast<uint64_t>(result)); break; case Any::TypeFloat: value = new NumberValue(static_cast<float>(result)); break; case Any::TypeDouble: value = new NumberValue(static_cast<double>(result)); break; case Any::TypeString: if (const char* string = static_cast<const char*>(result)) { value = new StringValue(string); } else { value = NullValue::getInstance(); } break; case Any::TypeObject: if (Object* unknown = static_cast<Object*>(result)) { ObjectValue* instance = new InterfacePointerValue(unknown); instance->setPrototype(getGlobal()->get(es::getInterface(Object::iid()).getName())->get("prototype")); // XXX Should use IID value = instance; } else { value = NullValue::getInstance(); } break; default: value = NullValue::getInstance(); break; } } break; case Reflect::kBoolean: value = BoolValue::getInstance(static_cast<bool>(apply(argc, argv, (bool (*)()) ((*self)[methodNumber])))); break; case Reflect::kOctet: value = new NumberValue(static_cast<uint8_t>(apply(argc, argv, (uint8_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kShort: value = new NumberValue(static_cast<int16_t>(apply(argc, argv, (int16_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kUnsignedShort: value = new NumberValue(static_cast<uint16_t>(apply(argc, argv, (uint16_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kLong: value = new NumberValue(static_cast<int32_t>(apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kUnsignedLong: value = new NumberValue(static_cast<uint32_t>(apply(argc, argv, (uint32_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kLongLong: value = new NumberValue(static_cast<int64_t>(apply(argc, argv, (int64_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kUnsignedLongLong: value = new NumberValue(static_cast<uint64_t>(apply(argc, argv, (uint64_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kFloat: value = new NumberValue(static_cast<float>(apply(argc, argv, (float (*)()) ((*self)[methodNumber])))); break; case Reflect::kDouble: value = new NumberValue(apply(argc, argv, (double (*)()) ((*self)[methodNumber]))); break; case Reflect::kPointer: value = new NumberValue(static_cast<intptr_t>(apply(argc, argv, (intptr_t (*)()) ((*self)[methodNumber])))); break; case Reflect::kString: { heap[0] = '\0'; Any result = apply(argc, argv, (const char* (*)()) ((*self)[methodNumber])); if (const char* string = static_cast<const char*>(result)) { value = new StringValue(string); } else { value = NullValue::getInstance(); } } break; case Reflect::kSequence: { // XXX Assume sequence<octet> now... int32_t count = apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber])); if (count < 0) { count = 0; } heap[count] = '\0'; value = new StringValue(heap); } break; case Reflect::kObject: if (Object* unknown = apply(argc, argv, (Object* (*)()) ((*self)[methodNumber]))) { ObjectValue* instance = new InterfacePointerValue(unknown); // TODO: check Object and others instance->setPrototype(getGlobal()->get(es::getInterface(returnType.getQualifiedName().c_str()).getName())->get("prototype")); // XXX Should use IID value = instance; } else { value = NullValue::getInstance(); } break; case Reflect::kVoid: apply(argc, argv, (int32_t (*)()) ((*self)[methodNumber])); value = NullValue::getInstance(); break; } return value; }
CompletionType evaluate() { Register<Value> value; switch (method) { case ToString: case ValueOf: if (!getThis()->isObject()) { throw getErrorInstance("TypeError"); } value = static_cast<ObjectValue*>(getThis())->getValueProperty(); if (!value->isString()) { throw getErrorInstance("TypeError"); } break; case CharAt: value = charAt(); break; case CharCodeAt: value = charCodeAt(); break; case Concat: value = concat(getThis()); break; case IndexOf: value = indexOf(getThis()); break; case LastIndexOf: value = lastIndexOf(getThis()); break; case LocaleCompare: value = localeCompare(getThis()); break; case Match: value = stringMatch(); break; case Replace: value = stringReplace(); break; case Search: value = stringSearch(); break; case Slice: value = slice(getThis()); break; case Split: value = stringSplit(); break; case Substring: value = substring(getThis()); break; case Substr: value = substr(getThis()); break; case ToLowerCase: case ToLocaleLowerCase: value = toLowerCase(getThis()); break; case ToUpperCase: case ToLocaleUpperCase: value = toUpperCase(getThis()); break; } return CompletionType(CompletionType::Return, value, ""); }