+2005-09-14 Maciej Stachowiak <mjs@apple.com>
+
+ Reviewed by Geoff.
+
+ - fixed <rdar://problem/4214783> REGRESSION: kjs_fast_malloc crash due to lack of locking on multiple threads (seen selecting volumes in the installer)
+
+ Make sure to lock using the InterpreterLock class in all places that need it
+ (including anything that uses the collector, the parser, the protect count hash table,
+ and anything that allocates via fast_malloc).
+
+ Also added assertions to ensure that the locking rules are followed for the relevant
+ resources.
+
+ * Makefile.am:
+ * bindings/NP_jsobject.cpp:
+ (identifierFromNPIdentifier):
+ (_NPN_Invoke):
+ (_NPN_Evaluate):
+ (_NPN_GetProperty):
+ (_NPN_SetProperty):
+ (_NPN_RemoveProperty):
+ (_NPN_HasProperty):
+ (_NPN_HasMethod):
+ (_NPN_SetException):
+ * bindings/jni/jni_jsobject.cpp:
+ (JSObject::call):
+ (JSObject::eval):
+ (JSObject::getMember):
+ (JSObject::setMember):
+ (JSObject::removeMember):
+ (JSObject::getSlot):
+ (JSObject::setSlot):
+ (JSObject::toString):
+ (JSObject::convertJObjectToValue):
+ * bindings/objc/WebScriptObject.mm:
+ (-[WebScriptObject callWebScriptMethod:withArguments:]):
+ (-[WebScriptObject evaluateWebScript:]):
+ (-[WebScriptObject setValue:forKey:]):
+ (-[WebScriptObject valueForKey:]):
+ (-[WebScriptObject removeWebScriptKey:]):
+ (-[WebScriptObject stringRepresentation]):
+ (-[WebScriptObject webScriptValueAtIndex:]):
+ (-[WebScriptObject setWebScriptValueAtIndex:value:]):
+ (+[WebScriptObject _convertValueToObjcValue:KJS::originExecutionContext:Bindings::executionContext:Bindings::]):
+ * bindings/runtime.cpp:
+ (Instance::createRuntimeObject):
+ * bindings/runtime_root.h:
+ * bindings/testbindings.cpp:
+ (main):
+ * bindings/testbindings.mm:
+ (main):
+ * kjs/fast_malloc.cpp:
+ (KJS::kjs_fast_malloc):
+ (KJS::kjs_fast_calloc):
+ (KJS::kjs_fast_free):
+ (KJS::kjs_fast_realloc):
+ * kjs/fast_malloc.h:
+ * kjs/identifier.h:
+ * kjs/internal.cpp:
+ (InterpreterImp::InterpreterImp):
+ (InterpreterImp::clear):
+ (InterpreterImp::mark):
+ (InterpreterImp::checkSyntax):
+ (InterpreterImp::evaluate):
+ * kjs/internal.h:
+ (KJS::InterpreterImp::globalObject):
+ * kjs/interpreter.cpp:
+ (Interpreter::evaluate):
+ * kjs/interpreter.h:
+ (KJS::InterpreterLock::InterpreterLock):
+ (KJS::InterpreterLock::~InterpreterLock):
+ * kjs/nodes.h:
+ * kjs/protect.h:
+ (KJS::ProtectedValue::ProtectedValue):
+ (KJS::ProtectedValue::~ProtectedValue):
+ (KJS::ProtectedValue::operator=):
+ (KJS::ProtectedObject::ProtectedObject):
+ (KJS::ProtectedObject::~ProtectedObject):
+ (KJS::ProtectedObject::operator=):
+ (KJS::ProtectedReference::ProtectedReference):
+ (KJS::ProtectedReference::~ProtectedReference):
+ (KJS::ProtectedReference::operator=):
+ * kjs/protected_object.h:
+ * kjs/protected_values.cpp:
+ (KJS::ProtectedValues::getProtectCount):
+ (KJS::ProtectedValues::increaseProtectCount):
+ (KJS::ProtectedValues::decreaseProtectCount):
+ * kjs/string_object.cpp:
+ (StringObjectImp::StringObjectImp):
+ * kjs/testkjs.cpp:
+ (main):
+
2005-09-16 Adele Peterson <adele@apple.com>
Change by Darin, reviewed by me and Maciej.
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
- 65305EAF08A58DDE00F31E73 /* protected_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 65305EAE08A58DDE00F31E73 /* protected_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 65305EB008A58E0900F31E73 /* protected_object.h in Headers */ = {isa = PBXBuildFile; fileRef = 65305EAE08A58DDE00F31E73 /* protected_object.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 652C107F08DA7B1E0020887D /* protected_reference.h in Headers */ = {isa = PBXBuildFile; fileRef = 652C107E08DA7B1E0020887D /* protected_reference.h */; };
65621E6D089E859700760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
65621E6E089E859700760F35 /* property_slot.h in Headers */ = {isa = PBXBuildFile; fileRef = 65621E6C089E859700760F35 /* property_slot.h */; settings = {ATTRIBUTES = (Private, ); }; };
65621E6F089E85D300760F35 /* property_slot.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 65621E6B089E859700760F35 /* property_slot.cpp */; };
651BDC78080F10CC00F10856 /* fast_malloc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = fast_malloc.h; sourceTree = "<group>"; };
651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = "<group>"; };
651F6413039D5B5F0078395C /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; };
- 65305EAE08A58DDE00F31E73 /* protected_object.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = protected_object.h; sourceTree = "<group>"; };
+ 652C107E08DA7B1E0020887D /* protected_reference.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = protected_reference.h; sourceTree = "<group>"; };
6541720E039E08B90058BFEB /* dftables.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dftables.c; path = pcre/dftables.c; sourceTree = "<group>"; };
6541720F039E08B90058BFEB /* pcre.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pcre.h; path = pcre/pcre.h; sourceTree = "<group>"; };
65417217039E0B280058BFEB /* pcre-config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = "pcre-config.h"; path = "pcre/pcre-config.h"; sourceTree = "<group>"; };
08FB77AEFE84172EC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
- 65305EAE08A58DDE00F31E73 /* protected_object.h */,
65EF2DF408BECC80000894BB /* shared_ptr.h */,
65621E6B089E859700760F35 /* property_slot.cpp */,
65621E6C089E859700760F35 /* property_slot.h */,
938772E5038BFE19008635CE /* array_instance.h */,
650B68D80639033F009D42DE /* protected_values.cpp */,
+ 652C107E08DA7B1E0020887D /* protected_reference.h */,
650B68D90639033F009D42DE /* protected_values.h */,
65AB004806261CBA0076DE63 /* interpreter_map.cpp */,
65AB004906261CBA0076DE63 /* interpreter_map.h */,
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- 65305EAF08A58DDE00F31E73 /* protected_object.h in Headers */,
932F5B400822A1C700736975 /* array_object.h in Headers */,
932F5B420822A1C700736975 /* collector.h in Headers */,
932F5B430822A1C700736975 /* date_object.h in Headers */,
93E26C1308B1523D00F85226 /* ucptable.c in Headers */,
93E26CCF08B2921900F85226 /* softlinking.h in Headers */,
65EF2DF508BECC80000894BB /* shared_ptr.h in Headers */,
+ 652C107F08DA7B1E0020887D /* protected_reference.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- 65305EB008A58E0900F31E73 /* protected_object.h in Headers */,
A85D81F8087B2822006A9172 /* array_object.h in Headers */,
A85D81F9087B2822006A9172 /* collector.h in Headers */,
A85D81FA087B2822006A9172 /* date_object.h in Headers */,
NPClass *NPScriptObjectClass = &_javascriptClass;
-static Identifier identiferFromNPIdentifier(const NPUTF8 *name)
+static Identifier identifierFromNPIdentifier(const NPUTF8 *name)
{
NPUTF16 *methodName;
unsigned int UTF16Length;
else {
// Lookup the function object.
ExecState *exec = obj->executionContext->interpreter()->globalExec();
- Interpreter::lock();
- ValueImp *func = obj->imp->get (exec, identiferFromNPIdentifier(i->value.string));
- Interpreter::unlock();
+ InterpreterLock lock;
+ ValueImp *func = obj->imp->get (exec, identifierFromNPIdentifier(i->value.string));
if (func->isNull()) {
NPN_InitializeVariantAsNull(result);
return false;
- }
- else if (func->isUndefined()) {
+ } else if (func->isUndefined()) {
NPN_InitializeVariantAsUndefined(result);
return false;
- }
- else {
+ } else {
// Call the function object.
ObjectImp *funcImp = static_cast<ObjectImp*>(func);
ObjectImp *thisObj = const_cast<ObjectImp*>(obj->imp);
List argList = listFromVariantArgs(exec, args, argCount);
- Interpreter::lock();
ValueImp *resultV = funcImp->call (exec, thisObj, argList);
- Interpreter::unlock();
// Convert and return the result of the function call.
convertValueToNPVariant(exec, resultV, result);
return true;
}
}
- }
- else {
- if (o->_class->invoke) {
- return o->_class->invoke (o, methodName, args, argCount, result);
- }
- }
+ } else if (o->_class->invoke)
+ return o->_class->invoke (o, methodName, args, argCount, result);
return true;
}
ExecState *exec = obj->executionContext->interpreter()->globalExec();
ValueImp *result;
- Interpreter::lock();
+ InterpreterLock lock;
NPUTF16 *scriptString;
unsigned int UTF16Length;
convertNPStringToUTF16 (s, &scriptString, &UTF16Length); // requires free() of returned memory.
else
result = Undefined();
- Interpreter::unlock();
-
free ((void *)scriptString);
convertValueToNPVariant(exec, result, variant);
PrivateIdentifier *i = (PrivateIdentifier *)propertyName;
- Interpreter::lock();
+ InterpreterLock lock;
ValueImp *result;
if (i->isString) {
- result = obj->imp->get (exec, identiferFromNPIdentifier(i->value.string));
- }
- else {
+ result = obj->imp->get (exec, identifierFromNPIdentifier(i->value.string));
+ } else {
result = obj->imp->get (exec, i->value.number);
}
- Interpreter::unlock();
if (result->isNull()) {
NPN_InitializeVariantAsNull(variant);
return false;
ExecState *exec = obj->executionContext->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
PrivateIdentifier *i = (PrivateIdentifier *)propertyName;
- if (i->isString) {
- obj->imp->put (exec, identiferFromNPIdentifier(i->value.string), convertNPVariantToValue(exec, variant));
- }
- else {
- obj->imp->put (exec, i->value.number, convertNPVariantToValue(exec, variant));
- }
- Interpreter::unlock();
+ if (i->isString)
+ obj->imp->put(exec, identifierFromNPIdentifier(i->value.string), convertNPVariantToValue(exec, variant));
+ else
+ obj->imp->put(exec, i->value.number, convertNPVariantToValue(exec, variant));
return true;
- }
- else if (o->_class->setProperty) {
+ } else if (o->_class->setProperty)
return o->_class->setProperty (o, propertyName, variant);
- }
+
return false;
}
PrivateIdentifier *i = (PrivateIdentifier *)propertyName;
if (i->isString) {
- if (!obj->imp->hasProperty (exec, identiferFromNPIdentifier(i->value.string))) {
+ if (!obj->imp->hasProperty (exec, identifierFromNPIdentifier(i->value.string))) {
return false;
}
}
}
}
- Interpreter::lock();
- if (i->isString) {
- obj->imp->deleteProperty (exec, identiferFromNPIdentifier(i->value.string));
- }
- else {
+ InterpreterLock lock;
+ if (i->isString)
+ obj->imp->deleteProperty (exec, identifierFromNPIdentifier(i->value.string));
+ else
obj->imp->deleteProperty (exec, i->value.number);
- }
- Interpreter::unlock();
return true;
}
ExecState *exec = obj->executionContext->interpreter()->globalExec();
PrivateIdentifier *i = (PrivateIdentifier *)propertyName;
- // String identifier?
- if (i->isString) {
- ExecState *exec = obj->executionContext->interpreter()->globalExec();
- Interpreter::lock();
- bool result = obj->imp->hasProperty (exec, identiferFromNPIdentifier(i->value.string));
- Interpreter::unlock();
- return result;
- }
+ InterpreterLock lock;
+
+ if (i->isString)
+ return obj->imp->hasProperty(exec, identifierFromNPIdentifier(i->value.string));
- // Numeric identifer
- Interpreter::lock();
- bool result = obj->imp->hasProperty (exec, i->value.number);
- Interpreter::unlock();
- return result;
- }
- else if (o->_class->hasProperty) {
+ return obj->imp->hasProperty(exec, i->value.number);
+ } else if (o->_class->hasProperty)
return o->_class->hasProperty (o, propertyName);
- }
return false;
}
// Lookup the function object.
ExecState *exec = obj->executionContext->interpreter()->globalExec();
- Interpreter::lock();
- ValueImp *func = obj->imp->get (exec, identiferFromNPIdentifier(i->value.string));
- Interpreter::unlock();
+
+ InterpreterLock lock;
+ ValueImp *func = obj->imp->get (exec, identifierFromNPIdentifier(i->value.string));
if (func->isUndefined()) {
return false;
if (o->_class == NPScriptObjectClass) {
JavaScriptObject *obj = (JavaScriptObject *)o;
ExecState *exec = obj->executionContext->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
throwError(exec, GeneralError, message);
- Interpreter::unlock();
}
}
// Lookup the function object.
ExecState *exec = _root->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
Identifier identifier(JavaString(methodName).ustring());
ValueImp *func = _imp->get (exec, identifier);
- Interpreter::unlock();
if (func->isUndefinedOrNull()) {
// Maybe throw an exception here?
return 0;
ObjectImp *funcImp = static_cast<ObjectImp*>(func);
ObjectImp *thisObj = const_cast<ObjectImp*>(_imp);
List argList = listFromJArray(args);
- Interpreter::lock();
- ValueImp *result = funcImp->call (exec, thisObj, argList);
- Interpreter::unlock();
+ ValueImp *result = funcImp->call(exec, thisObj, argList);
- // Convert and return the result of the function call.
- return convertValueToJObject (result);
+ return convertValueToJObject(result);
}
jobject JSObject::eval(jstring script) const
{
JS_LOG ("script = %s\n", JavaString(script).UTF8String());
-
+
ObjectImp *thisObj = const_cast<ObjectImp*>(_imp);
ValueImp *result;
- Interpreter::lock();
-
+ InterpreterLock lock;
+
Completion completion = _root->interpreter()->evaluate(UString(), 0, JavaString(script).ustring(),thisObj);
ComplType type = completion.complType();
if (type == Normal) {
result = completion.value();
- if (!result) {
+ if (!result)
result = Undefined();
- }
- }
- else
+ } else
result = Undefined();
-
- Interpreter::unlock();
return convertValueToJObject (result);
}
JS_LOG ("(%p) memberName = %s\n", _imp, JavaString(memberName).UTF8String());
ExecState *exec = _root->interpreter()->globalExec();
-
- Interpreter::lock();
+
+ InterpreterLock lock;
ValueImp *result = _imp->get (exec, Identifier (JavaString(memberName).ustring()));
- Interpreter::unlock();
- return convertValueToJObject (result);
+ return convertValueToJObject(result);
}
void JSObject::setMember(jstring memberName, jobject value) const
{
JS_LOG ("memberName = %s, value = %p\n", JavaString(memberName).UTF8String(), value);
ExecState *exec = _root->interpreter()->globalExec();
- Interpreter::lock();
- _imp->put (exec, Identifier (JavaString(memberName).ustring()), convertJObjectToValue(value));
- Interpreter::unlock();
+ InterpreterLock lock;
+ _imp->put(exec, Identifier (JavaString(memberName).ustring()), convertJObjectToValue(value));
}
JS_LOG ("memberName = %s\n", JavaString(memberName).UTF8String());
ExecState *exec = _root->interpreter()->globalExec();
- Interpreter::lock();
- _imp->deleteProperty (exec, Identifier (JavaString(memberName).ustring()));
- Interpreter::unlock();
+ InterpreterLock lock;
+ _imp->deleteProperty(exec, Identifier (JavaString(memberName).ustring()));
}
JS_LOG ("index = %ld\n", index);
ExecState *exec = _root->interpreter()->globalExec();
- Interpreter::lock();
+
+ InterpreterLock lock;
ValueImp *result = _imp->get (exec, (unsigned)index);
- Interpreter::unlock();
- return convertValueToJObject (result);
+ return convertValueToJObject(result);
}
JS_LOG ("index = %ld, value = %p\n", index, value);
ExecState *exec = _root->interpreter()->globalExec();
- Interpreter::lock();
- _imp->put (exec, (unsigned)index, convertJObjectToValue(value));
- Interpreter::unlock();
+ InterpreterLock lock;
+ _imp->put(exec, (unsigned)index, convertJObjectToValue(value));
}
jstring JSObject::toString() const
{
JS_LOG ("\n");
-
- Interpreter::lock();
+
+ InterpreterLock lock;
ObjectImp *thisObj = const_cast<ObjectImp*>(_imp);
ExecState *exec = _root->interpreter()->globalExec();
- jstring result = (jstring)convertValueToJValue (exec, thisObj, object_type, "java.lang.String").l;
-
- Interpreter::unlock();
-
- return result;
+ return (jstring)convertValueToJValue (exec, thisObj, object_type, "java.lang.String").l;
}
void JSObject::finalize() const
return imp;
}
- Interpreter::lock();
+ InterpreterLock lock;
RuntimeObjectImp *newImp = new RuntimeObjectImp(new Bindings::JavaInstance (theObject, _root));
- Interpreter::unlock();
return newImp;
}
// Lookup the function object.
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
ValueImp *v = convertObjcValueToValue(exec, &name, ObjcObjectType);
Identifier identifier(v->toString(exec));
ValueImp *func = [self _imp]->get (exec, identifier);
- Interpreter::unlock();
+
if (!func || func->isUndefined()) {
// Maybe throw an exception here?
return 0;
}
// Call the function object.
- Interpreter::lock();
ObjectImp *funcImp = static_cast<ObjectImp*>(func);
ObjectImp *thisObj = const_cast<ObjectImp*>([self _imp]);
List argList = listFromNSArray(exec, args);
ValueImp *result = funcImp->call (exec, thisObj, argList);
- Interpreter::unlock();
if (exec->hadException()) {
LOG_EXCEPTION (exec);
{
if (![self _executionContext])
return nil;
-
+
if (![self _isSafeScript])
return nil;
-
+
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
-
ValueImp *result;
- Interpreter::lock();
+ InterpreterLock lock;
ValueImp *v = convertObjcValueToValue(exec, &script, ObjcObjectType);
Completion completion = [self _executionContext]->interpreter()->evaluate(UString(), 0, v->toString(exec));
if (type == Normal) {
result = completion.value();
- if (!result) {
+ if (!result)
result = Undefined();
- }
- }
- else
+ } else
result = Undefined();
-
- Interpreter::unlock();
if (exec->hadException()) {
LOG_EXCEPTION (exec);
result = Undefined();
}
-
+
id resultObj = [WebScriptObject _convertValueToObjcValue:result originExecutionContext:[self _originExecutionContext] executionContext:[self _executionContext]];
-
+
_didExecute(self);
return resultObj;
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
ValueImp *v = convertObjcValueToValue(exec, &key, ObjcObjectType);
[self _imp]->put (exec, Identifier (v->toString(exec)), (convertObjcValueToValue(exec, &value, ObjcObjectType)));
- Interpreter::unlock();
if (exec->hadException()) {
LOG_EXCEPTION (exec);
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
ValueImp *v = convertObjcValueToValue(exec, &key, ObjcObjectType);
ValueImp *result = [self _imp]->get (exec, Identifier (v->toString(exec)));
- Interpreter::unlock();
if (exec->hadException()) {
LOG_EXCEPTION (exec);
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
ValueImp *v = convertObjcValueToValue(exec, &key, ObjcObjectType);
[self _imp]->deleteProperty (exec, Identifier (v->toString(exec)));
- Interpreter::unlock();
if (exec->hadException()) {
LOG_EXCEPTION (exec);
// This is a workaround for a gcc 3.3 internal compiler error.
return @"Undefined";
- Interpreter::lock();
+ InterpreterLock lock;
ObjectImp *thisObj = const_cast<ObjectImp*>([self _imp]);
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
id result = convertValueToObjcValue(exec, thisObj, ObjcObjectType).objectValue;
- Interpreter::unlock();
-
id resultObj = [result description];
_didExecute(self);
return nil;
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
ValueImp *result = [self _imp]->get (exec, (unsigned)index);
- Interpreter::unlock();
if (exec->hadException()) {
LOG_EXCEPTION (exec);
return;
ExecState *exec = [self _executionContext]->interpreter()->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
[self _imp]->put (exec, (unsigned)index, (convertObjcValueToValue(exec, &value, ObjcObjectType)));
- Interpreter::unlock();
if (exec->hadException()) {
LOG_EXCEPTION (exec);
+ (id)_convertValueToObjcValue:(ValueImp *)value originExecutionContext:(const RootObject *)originExecutionContext executionContext:(const RootObject *)executionContext
{
- id result = 0;
-
// First see if we have a ObjC instance.
if (value->isObject()) {
ObjectImp *objectImp = static_cast<ObjectImp*>(value);
Interpreter *intepreter = executionContext->interpreter();
ExecState *exec = intepreter->globalExec();
- Interpreter::lock();
+ InterpreterLock lock;
if (objectImp->classInfo() != &RuntimeObjectImp::info) {
ValueImp *runtimeObject = objectImp->get(exec, "__apple_runtime_object");
if (runtimeObject && runtimeObject->isObject())
objectImp = static_cast<RuntimeObjectImp*>(runtimeObject);
}
-
- Interpreter::unlock();
if (objectImp->classInfo() == &RuntimeObjectImp::info) {
RuntimeObjectImp *imp = static_cast<RuntimeObjectImp *>(objectImp);
ObjcInstance *instance = static_cast<ObjcInstance*>(imp->getInternalInstance());
if (instance)
- result = instance->getObject();
- }
- // Convert to a WebScriptObject
- else {
- result = (id)intepreter->createLanguageInstanceForValue (exec, Instance::ObjectiveCLanguage, value->toObject(exec), originExecutionContext, executionContext);
- }
- }
-
- // Convert JavaScript String value to NSString?
- else if (value->isString()) {
+ return instance->getObject();
+ } else
+ // JS Object --> WebScriptObject
+ return (id)intepreter->createLanguageInstanceForValue (exec, Instance::ObjectiveCLanguage, value->toObject(exec), originExecutionContext, executionContext);
+ } else if (value->isString()) {
+ // JS String --> NSString
StringImp *s = static_cast<StringImp*>(value);
UString u = s->value();
NSString *string = [NSString stringWithCharacters:(const unichar*)u.data() length:u.size()];
- result = string;
- }
-
- // Convert JavaScript Number value to NSNumber?
- else if (value->isNumber()) {
- result = [NSNumber numberWithDouble:value->getNumber()];
- }
-
- else if (value->isBoolean()) {
- BooleanImp *b = static_cast<BooleanImp*>(value);
- result = [NSNumber numberWithBool:b->value()];
- }
-
- // Convert JavaScript Undefined types to WebUndefined
- else if (value->isUndefined()) {
- result = [WebUndefined undefined];
- }
+ return string;
+ } else if (value->isNumber())
+ // JS Number --> NSNumber
+ return [NSNumber numberWithDouble:value->getNumber()];
+ else if (value->isBoolean())
+ // JS Boolean --> NSNumber
+ return [NSNumber numberWithBool:static_cast<BooleanImp*>(value)->value()];
+ else if (value->isUndefined())
+ // JS Undefined --> WebUndefined
+ return [WebUndefined undefined];
// Other types (UnspecifiedType and NullType) converted to 0.
-
- return result;
+ return 0;
}
@end
ObjectImp *Instance::createRuntimeObject (BindingLanguage language, void *nativeInstance, const RootObject *executionContext)
{
- Instance *interfaceObject = Instance::createBindingForLanguageInstance (language, (void *)nativeInstance, executionContext);
+ Instance *interfaceObject = Instance::createBindingForLanguageInstance(language, (void *)nativeInstance, executionContext);
- Interpreter::lock();
- ObjectImp *theObject(new RuntimeObjectImp(interfaceObject,true));
- Interpreter::unlock();
-
- return theObject;
+ InterpreterLock lock;
+ return new RuntimeObjectImp(interfaceObject,true);
}
void *Instance::createLanguageInstanceForValue (ExecState *exec, BindingLanguage language, ObjectImp *value, const RootObject *origin, const RootObject *current)
#include <JavaScriptCore/object.h>
#include <JavaScriptCore/protect.h>
#include <JavaScriptCore/jni_jsobject.h>
+#include <JavaScriptCore/protect.h>
namespace KJS {
bool ret = true;
{
- Interpreter::lock();
+ InterpreterLock lock;
// create interpreter w/ global object
Object global(new GlobalImp());
NPN_ReleaseObject ((NPObject *)myObject);
- Interpreter::unlock();
-
} // end block, so that Interpreter and global get deleted
return ret ? 0 : 3;
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- Interpreter::lock();
+ InterpreterLock lock;
// create interpreter w/ global object
Object global(new GlobalImp());
[myInterface release];
- Interpreter::unlock();
-
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_3
[pool release];
#else
#define MORECORE_CANNOT_TRIM 1
#endif
+#include "internal.h"
+
namespace KJS {
#ifndef NDEBUG
void *kjs_fast_malloc(size_t n)
{
+ assert(InterpreterImp::lockCount() > 0);
return malloc(n);
}
void *kjs_fast_calloc(size_t n_elements, size_t element_size)
{
+ assert(InterpreterImp::lockCount() > 0);
return calloc(n_elements, element_size);
}
void kjs_fast_free(void* p)
{
+ assert(InterpreterImp::lockCount() > 0);
free(p);
}
void *kjs_fast_realloc(void* p, size_t n)
{
+ assert(InterpreterImp::lockCount() > 0);
return realloc(p, n);
}
#endif /* WIN32 */
-#endif
+#endif // NDEBUG
} /* end of namespace KJS */
macro(arguments) \
macro(callee) \
macro(constructor) \
+ macro(fromCharCode) \
macro(length) \
macro(message) \
macro(name) \
-// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
{
// add this interpreter to the global chain
// as a root set for garbage collection
- lockInterpreter();
+ InterpreterLock lock;
+
m_interpreter = interp;
if (s_hook) {
prev = s_hook;
initGlobalObject();
recursion = 0;
- unlockInterpreter();
}
void InterpreterImp::lock()
{
//fprintf(stderr,"InterpreterImp::clear\n");
// remove from global chain (see init())
-#if APPLE_CHANGES
- lockInterpreter();
-#endif
+ InterpreterLock lock;
+
next->prev = prev;
prev->next = next;
s_hook = next;
globalClear();
}
InterpreterMap::removeInterpreterForGlobalObject(global);
-
-#if APPLE_CHANGES
- unlockInterpreter();
-#endif
}
void InterpreterImp::mark()
m_interpreter->mark();
if (_context)
_context->mark();
+ if (global)
+ global->mark();
+ if (globExec._exception)
+ globExec._exception->mark();
}
bool InterpreterImp::checkSyntax(const UString &code)
{
+ InterpreterLock lock;
+
// Parser::parse() returns 0 in a syntax error occurs, so we just check for that
SharedPtr<ProgramNode> progNode = Parser::parse(UString(), 0, code.data(),code.size(),0,0,0);
return progNode;
Completion InterpreterImp::evaluate(const UString &code, ValueImp *thisV, const UString &sourceURL, int startingLineNumber)
{
-#if APPLE_CHANGES
- lockInterpreter();
-#endif
+ InterpreterLock lock;
+
// prevent against infinite recursion
if (recursion >= 20) {
#if APPLE_CHANGES
Completion result = Completion(Throw, Error::create(&globExec, GeneralError, "Recursion too deep"));
- unlockInterpreter();
return result;
#else
return Completion(Throw,Error::create(&globExec, GeneralError, "Recursion too deep"));
#endif
}
-
+
// parse the source code
int sid;
int errLine;
if (dbg) {
bool cont = dbg->sourceParsed(&globExec, sid, sourceURL, code, errLine);
if (!cont)
-#if APPLE_CHANGES
- {
- unlockInterpreter();
- return Completion(Break);
- }
-#else
return Completion(Break);
-#endif
}
// no program node means a syntax error occurred
if (!progNode) {
ObjectImp *err = Error::create(&globExec, SyntaxError, errMsg, errLine, sid, &sourceURL);
-#if APPLE_CHANGES
- unlockInterpreter();
-#endif
return Completion(Throw,err);
}
else {
// execute the code
ContextImp ctx(globalObj, this, thisObj);
- ExecState newExec(m_interpreter,&ctx);
+ ExecState newExec(m_interpreter, &ctx);
progNode->processVarDecls(&newExec);
res = progNode->execute(&newExec);
}
recursion--;
-#if APPLE_CHANGES
- unlockInterpreter();
-#endif
return res;
}
#include "ustring.h"
#include "value.h"
#include "object.h"
-#include "protected_object.h"
+#include "protect.h"
#include "types.h"
#include "interpreter.h"
#include "scope_chain.h"
class SavedBuiltinsInternal {
friend class InterpreterImp;
private:
- ProtectedObject b_Object;
- ProtectedObject b_Function;
- ProtectedObject b_Array;
- ProtectedObject b_Boolean;
- ProtectedObject b_String;
- ProtectedObject b_Number;
- ProtectedObject b_Date;
- ProtectedObject b_RegExp;
- ProtectedObject b_Error;
-
- ProtectedObject b_ObjectPrototype;
- ProtectedObject b_FunctionPrototype;
- ProtectedObject b_ArrayPrototype;
- ProtectedObject b_BooleanPrototype;
- ProtectedObject b_StringPrototype;
- ProtectedObject b_NumberPrototype;
- ProtectedObject b_DatePrototype;
- ProtectedObject b_RegExpPrototype;
- ProtectedObject b_ErrorPrototype;
-
- ProtectedObject b_evalError;
- ProtectedObject b_rangeError;
- ProtectedObject b_referenceError;
- ProtectedObject b_syntaxError;
- ProtectedObject b_typeError;
- ProtectedObject b_uriError;
-
- ProtectedObject b_evalErrorPrototype;
- ProtectedObject b_rangeErrorPrototype;
- ProtectedObject b_referenceErrorPrototype;
- ProtectedObject b_syntaxErrorPrototype;
- ProtectedObject b_typeErrorPrototype;
- ProtectedObject b_uriErrorPrototype;
+ ProtectedPtr<ObjectImp> b_Object;
+ ProtectedPtr<ObjectImp> b_Function;
+ ProtectedPtr<ObjectImp> b_Array;
+ ProtectedPtr<ObjectImp> b_Boolean;
+ ProtectedPtr<ObjectImp> b_String;
+ ProtectedPtr<ObjectImp> b_Number;
+ ProtectedPtr<ObjectImp> b_Date;
+ ProtectedPtr<ObjectImp> b_RegExp;
+ ProtectedPtr<ObjectImp> b_Error;
+
+ ProtectedPtr<ObjectImp> b_ObjectPrototype;
+ ProtectedPtr<ObjectImp> b_FunctionPrototype;
+ ProtectedPtr<ObjectImp> b_ArrayPrototype;
+ ProtectedPtr<ObjectImp> b_BooleanPrototype;
+ ProtectedPtr<ObjectImp> b_StringPrototype;
+ ProtectedPtr<ObjectImp> b_NumberPrototype;
+ ProtectedPtr<ObjectImp> b_DatePrototype;
+ ProtectedPtr<ObjectImp> b_RegExpPrototype;
+ ProtectedPtr<ObjectImp> b_ErrorPrototype;
+
+ ProtectedPtr<ObjectImp> b_evalError;
+ ProtectedPtr<ObjectImp> b_rangeError;
+ ProtectedPtr<ObjectImp> b_referenceError;
+ ProtectedPtr<ObjectImp> b_syntaxError;
+ ProtectedPtr<ObjectImp> b_typeError;
+ ProtectedPtr<ObjectImp> b_uriError;
+
+ ProtectedPtr<ObjectImp> b_evalErrorPrototype;
+ ProtectedPtr<ObjectImp> b_rangeErrorPrototype;
+ ProtectedPtr<ObjectImp> b_referenceErrorPrototype;
+ ProtectedPtr<ObjectImp> b_syntaxErrorPrototype;
+ ProtectedPtr<ObjectImp> b_typeErrorPrototype;
+ ProtectedPtr<ObjectImp> b_uriErrorPrototype;
};
class InterpreterImp {
InterpreterImp(Interpreter *interp, ObjectImp *glob);
~InterpreterImp();
- ProtectedObject &globalObject() const { return const_cast<ProtectedObject &>(global); }
- Interpreter* interpreter() const { return m_interpreter; }
+ ObjectImp *globalObject() { return global; }
+ Interpreter *interpreter() const { return m_interpreter; }
void initGlobalObject();
static void lock();
private:
void clear();
Interpreter *m_interpreter;
- ProtectedObject global;
+ ObjectImp *global;
Debugger *dbg;
// Built-in properties of the object prototype. These are accessible
// from here even if they are replaced by js code (e.g. assigning to
// Array.prototype)
- ProtectedObject b_Object;
- ProtectedObject b_Function;
- ProtectedObject b_Array;
- ProtectedObject b_Boolean;
- ProtectedObject b_String;
- ProtectedObject b_Number;
- ProtectedObject b_Date;
- ProtectedObject b_RegExp;
- ProtectedObject b_Error;
-
- ProtectedObject b_ObjectPrototype;
- ProtectedObject b_FunctionPrototype;
- ProtectedObject b_ArrayPrototype;
- ProtectedObject b_BooleanPrototype;
- ProtectedObject b_StringPrototype;
- ProtectedObject b_NumberPrototype;
- ProtectedObject b_DatePrototype;
- ProtectedObject b_RegExpPrototype;
- ProtectedObject b_ErrorPrototype;
-
- ProtectedObject b_evalError;
- ProtectedObject b_rangeError;
- ProtectedObject b_referenceError;
- ProtectedObject b_syntaxError;
- ProtectedObject b_typeError;
- ProtectedObject b_uriError;
-
- ProtectedObject b_evalErrorPrototype;
- ProtectedObject b_rangeErrorPrototype;
- ProtectedObject b_referenceErrorPrototype;
- ProtectedObject b_syntaxErrorPrototype;
- ProtectedObject b_typeErrorPrototype;
- ProtectedObject b_uriErrorPrototype;
+ ProtectedPtr<ObjectImp> b_Object;
+ ProtectedPtr<ObjectImp> b_Function;
+ ProtectedPtr<ObjectImp> b_Array;
+ ProtectedPtr<ObjectImp> b_Boolean;
+ ProtectedPtr<ObjectImp> b_String;
+ ProtectedPtr<ObjectImp> b_Number;
+ ProtectedPtr<ObjectImp> b_Date;
+ ProtectedPtr<ObjectImp> b_RegExp;
+ ProtectedPtr<ObjectImp> b_Error;
+
+ ProtectedPtr<ObjectImp> b_ObjectPrototype;
+ ProtectedPtr<ObjectImp> b_FunctionPrototype;
+ ProtectedPtr<ObjectImp> b_ArrayPrototype;
+ ProtectedPtr<ObjectImp> b_BooleanPrototype;
+ ProtectedPtr<ObjectImp> b_StringPrototype;
+ ProtectedPtr<ObjectImp> b_NumberPrototype;
+ ProtectedPtr<ObjectImp> b_DatePrototype;
+ ProtectedPtr<ObjectImp> b_RegExpPrototype;
+ ProtectedPtr<ObjectImp> b_ErrorPrototype;
+
+ ProtectedPtr<ObjectImp> b_evalError;
+ ProtectedPtr<ObjectImp> b_rangeError;
+ ProtectedPtr<ObjectImp> b_referenceError;
+ ProtectedPtr<ObjectImp> b_syntaxError;
+ ProtectedPtr<ObjectImp> b_typeError;
+ ProtectedPtr<ObjectImp> b_uriError;
+
+ ProtectedPtr<ObjectImp> b_evalErrorPrototype;
+ ProtectedPtr<ObjectImp> b_rangeErrorPrototype;
+ ProtectedPtr<ObjectImp> b_referenceErrorPrototype;
+ ProtectedPtr<ObjectImp> b_syntaxErrorPrototype;
+ ProtectedPtr<ObjectImp> b_typeErrorPrototype;
+ ProtectedPtr<ObjectImp> b_uriErrorPrototype;
ExecState globExec;
Interpreter::CompatMode m_compatMode;
#if APPLE_CHANGES
if (shouldPrintExceptions() && comp.complType() == Throw) {
- lock();
+ InterpreterLock lock;
ExecState *exec = rep->globalExec();
char *f = strdup(sourceURL.ascii());
const char *message = comp.value()->toObject(exec)->toString(exec).ascii();
printf("[%d] %s:%s\n", getpid(), f, message);
free(f);
- unlock();
}
#endif
-// -*- c-basic-offset: 2 -*-
/*
* This file is part of the KDE libraries
* Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
ValueImp *_exception;
};
+ class InterpreterLock
+ {
+ public:
+ InterpreterLock() { Interpreter::lock(); }
+ ~InterpreterLock() { Interpreter::unlock(); }
+ private:
+ InterpreterLock(const InterpreterLock &);
+ InterpreterLock &operator =(const InterpreterLock &);
+ };
+
} // namespace
#endif // _KJS_INTERPRETER_H_
namespace KJS {
+ class ProgramNode;
+ class PropertyNode;
+ class PropertyValueNode;
+ class Reference;
class RegExp;
class SourceElementsNode;
- class ProgramNode;
class SourceStream;
- class PropertyValueNode;
- class PropertyNode;
enum Operator { OpEqual,
OpEqEq,
class SavedProperty {
public:
Identifier key;
- ProtectedValue value;
+ ProtectedPtr<ValueImp> value;
int attributes;
};
#include "reference.h"
#include "value.h"
#include "protected_values.h"
+#include "interpreter.h"
namespace KJS {
inline void gcProtect(ValueImp *val)
- {
+ {
ProtectedValues::increaseProtectCount(val);
- }
+ }
+
inline void gcUnprotect(ValueImp *val)
- {
+ {
ProtectedValues::decreaseProtectCount(val);
- }
+ }
inline void gcProtectNullTolerant(ValueImp *val)
- {
+ {
if (val) gcProtect(val);
- }
+ }
inline void gcUnprotectNullTolerant(ValueImp *val)
- {
+ {
if (val) gcUnprotect(val);
- }
+ }
-class ProtectedValue {
-public:
- ProtectedValue() : m_value(0) { }
- ProtectedValue(ValueImp *v) : m_value(v) { gcProtectNullTolerant(v); }
- ProtectedValue(const ProtectedValue& v) : m_value(v.m_value) { gcProtectNullTolerant(m_value); }
- ~ProtectedValue() { gcUnprotectNullTolerant(m_value); }
- ProtectedValue& operator=(ValueImp *v)
+ // FIXME: Share more code with SharedPtr template? The only difference is the ref/deref operation.
+ template <class T> class ProtectedPtr {
+ public:
+ ProtectedPtr() : m_ptr(NULL) { }
+ ProtectedPtr(T *ptr);
+ ProtectedPtr(const ProtectedPtr &);
+ ~ProtectedPtr();
+
+ template <class U> ProtectedPtr(const ProtectedPtr<U> &);
+
+ T *get() const { return m_ptr; }
+ operator T *() const { return m_ptr; }
+ T *operator->() const { return m_ptr; }
+
+ bool operator!() const { return m_ptr == NULL; }
+ operator bool() const { return m_ptr != NULL; }
+
+ ProtectedPtr &operator=(const ProtectedPtr &);
+ ProtectedPtr &operator=(T *);
+
+ private:
+ T *m_ptr;
+
+ operator int() const; // deliberately not implemented; helps prevent operator bool from converting to int accidentally
+ };
+
+ template <class T> ProtectedPtr<T>::ProtectedPtr(T *ptr)
+ : m_ptr(ptr)
+ {
+ if (ptr) {
+ InterpreterLock lock;
+ gcProtect(ptr);
+ }
+ }
+
+ template <class T> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr &o)
+ : m_ptr(o.get())
{
- gcProtectNullTolerant(v);
- gcUnprotectNullTolerant(m_value);
- m_value = v;
+ if (T *ptr = m_ptr) {
+ InterpreterLock lock;
+ gcProtect(ptr);
+ }
+ }
+
+ template <class T> ProtectedPtr<T>::~ProtectedPtr()
+ {
+ if (T *ptr = m_ptr) {
+ InterpreterLock lock;
+ gcUnprotect(ptr);
+ }
+ }
+
+ template <class T> template <class U> ProtectedPtr<T>::ProtectedPtr(const ProtectedPtr<U> &o)
+ : m_ptr(o.get())
+ {
+ if (T *ptr = m_ptr) {
+ InterpreterLock lock;
+ gcProtect(ptr);
+ }
+ }
+
+ template <class T> ProtectedPtr<T> &ProtectedPtr<T>::operator=(const ProtectedPtr<T> &o)
+ {
+ InterpreterLock lock;
+ T *optr = o.m_ptr;
+ gcProtectNullTolerant(optr);
+ gcUnprotectNullTolerant(m_ptr);
+ m_ptr = optr;
+ return *this;
+ }
+
+ template <class T> inline ProtectedPtr<T> &ProtectedPtr<T>::operator=(T *optr)
+ {
+ InterpreterLock lock;
+ gcProtectNullTolerant(optr);
+ gcUnprotectNullTolerant(m_ptr);
+ m_ptr = optr;
return *this;
}
- ProtectedValue& operator=(const ProtectedValue& v) { return *this = v.m_value; }
- operator ValueImp *() const { return m_value; }
- ValueImp *operator->() const { return m_value; }
-protected:
- ValueImp *m_value;
-};
+ template <class T> inline bool operator==(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() == b.get(); }
+ template <class T> inline bool operator==(const ProtectedPtr<T> &a, const T *b) { return a.get() == b; }
+ template <class T> inline bool operator==(const T *a, const ProtectedPtr<T> &b) { return a == b.get(); }
+
+ template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const ProtectedPtr<T> &b) { return a.get() != b.get(); }
+ template <class T> inline bool operator!=(const ProtectedPtr<T> &a, const T *b) { return a.get() != b; }
+ template <class T> inline bool operator!=(const T *a, const ProtectedPtr<T> &b) { return a != b.get(); }
+
} // namespace
#endif
+++ /dev/null
-/*
- * This file is part of the KDE libraries
- * Copyright (C) 2004 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- */
-
-#ifndef KJS_PROTECTED_OBJECT_H
-#define KJS_PROTECTED_OBJECT_H
-
-#include "protect.h"
-#include "object.h"
-#include "reference.h"
-
-namespace KJS {
-
-class ProtectedObject : private ProtectedValue {
-public:
- ProtectedObject() { }
- ProtectedObject(ObjectImp *v) : ProtectedValue(v) { }
- ProtectedObject(const ProtectedObject& v) : ProtectedValue(v) { }
- ProtectedObject& operator=(ObjectImp *v) { ProtectedValue::operator=(v); return *this; }
- ProtectedObject& operator=(const ProtectedObject& v) { ProtectedValue::operator=(v); return *this; }
- operator ValueImp *() const { return m_value; }
- operator ObjectImp *() const { return static_cast<ObjectImp *>(m_value); }
- ObjectImp *operator->() const { return static_cast<ObjectImp *>(m_value); }
-};
-
- class ProtectedReference : public Reference {
- public:
- ProtectedReference(const Reference& r) : Reference(r) { gcProtectNullTolerant(r.base); };
- ~ProtectedReference() { gcUnprotectNullTolerant(base);}
- ProtectedReference& operator=(const Reference &r)
- {
- ValueImp *old = base;
- Reference::operator=(r);
- gcProtectNullTolerant(r.base);
- gcUnprotectNullTolerant(old);
- return *this;
- }
- private:
- ProtectedReference();
- ProtectedReference(ObjectImp *b, const Identifier& p);
- ProtectedReference(ObjectImp *b, unsigned p);
- ProtectedReference(const Identifier& p);
- ProtectedReference(unsigned p);
- };
-
-} // namespace
-
-#endif
#include "pointer_hash.h"
#include "simple_number.h"
+#include "internal.h"
#include <stdint.h>
#include "value.h"
int ProtectedValues::getProtectCount(ValueImp *k)
{
+ assert(k);
+ assert(InterpreterImp::lockCount() > 0);
+
if (!_table)
return 0;
void ProtectedValues::increaseProtectCount(ValueImp *k)
{
assert(k);
+ assert(InterpreterImp::lockCount() > 0);
if (SimpleNumber::is(k))
return;
void ProtectedValues::decreaseProtectCount(ValueImp *k)
{
assert(k);
+ assert(InterpreterImp::lockCount() > 0);
if (SimpleNumber::is(k))
return;
class Reference {
friend class ReferenceList;
friend class ReferenceListIterator;
- friend class ProtectedReference;
public:
Reference(ObjectImp *b, const Identifier& p);
Reference(ObjectImp *b, unsigned p);
ValueImp *baseIfMutable() const { return baseIsValue ? 0 : base; }
+ protected:
+ ValueImp *base;
+
private:
Reference() { }
- ValueImp *base;
unsigned propertyNameAsNumber;
bool baseIsValue;
bool propertyNameIsNumber;
*/
#include "reference_list.h"
-
-#include "protected_object.h"
+#include "protected_reference.h"
namespace KJS {
class ReferenceListNode {
// ECMA 15.5.3.1 String.prototype
putDirect(prototypePropertyName, stringProto, DontEnum|DontDelete|ReadOnly);
- static Identifier fromCharCode("fromCharCode");
- putDirect(fromCharCode, new StringObjectFuncImp(exec,funcProto), DontEnum);
+ putDirect(fromCharCodePropertyName, new StringObjectFuncImp(exec, funcProto), DontEnum);
// no. of arguments for constructor
putDirect(lengthPropertyName, jsOne(), ReadOnly|DontDelete|DontEnum);
bool ret = true;
{
- Interpreter::lock();
+ InterpreterLock lock;
ObjectImp *global(new GlobalImp());
free(code);
}
-
- Interpreter::unlock();
- } // end block, so that Interpreter and global get deleted
+ } // end block, so that interpreter gets deleted
if (ret)
fprintf(stderr, "OK.\n");